Correctly restore gnutls_record_recv() in DTLS mode if interrupted during the retrasm...
[gnutls.git] / lib / minitasn1 / parser_aux.c
blob2e1f7eeecb813e170425a8e42bb8b172a742458b
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 "parser_aux.h"
24 #include "gstr.h"
25 #include "structure.h"
26 #include "element.h"
28 char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */
30 /***********************************************/
31 /* Type: list_type */
32 /* Description: type used in the list during */
33 /* the structure creation. */
34 /***********************************************/
35 typedef struct list_struct
37 ASN1_TYPE node;
38 struct list_struct *next;
39 } list_type;
42 /* Pointer to the first element of the list */
43 list_type *firstElement = NULL;
45 /******************************************************/
46 /* Function : _asn1_add_node */
47 /* Description: creates a new NODE_ASN element and */
48 /* puts it in the list pointed by firstElement. */
49 /* Parameters: */
50 /* type: type of the new element (see TYPE_ */
51 /* and CONST_ constants). */
52 /* Return: pointer to the new element. */
53 /******************************************************/
54 ASN1_TYPE
55 _asn1_add_node (unsigned int type)
57 list_type *listElement;
58 ASN1_TYPE punt;
60 punt = (ASN1_TYPE) _asn1_calloc (1, sizeof (struct node_asn_struct));
61 if (punt == NULL)
62 return NULL;
64 listElement = (list_type *) _asn1_malloc (sizeof (list_type));
65 if (listElement == NULL)
67 _asn1_free (punt);
68 return NULL;
71 listElement->node = punt;
72 listElement->next = firstElement;
73 firstElement = listElement;
75 punt->type = type;
77 return punt;
80 /**
81 * asn1_find_node:
82 * @pointer: NODE_ASN element pointer.
83 * @name: null terminated string with the element's name to find.
85 * Searches for an element called @name starting from @pointer. The
86 * name is composed by differents identifiers separated by dots. When
87 * *@pointer has a name, the first identifier must be the name of
88 * *@pointer, otherwise it must be the name of one child of *@pointer.
90 * Returns: the search result, or %NULL if not found.
91 **/
92 ASN1_TYPE
93 asn1_find_node (ASN1_TYPE pointer, const char *name)
95 ASN1_TYPE p;
96 char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
97 const char *n_start;
99 if (pointer == NULL)
100 return NULL;
102 if (name == NULL)
103 return NULL;
105 p = pointer;
106 n_start = name;
108 if (p->name != NULL)
109 { /* has *pointer got a name ? */
110 n_end = strchr (n_start, '.'); /* search the first dot */
111 if (n_end)
113 memcpy (n, n_start, n_end - n_start);
114 n[n_end - n_start] = 0;
115 n_start = n_end;
116 n_start++;
118 else
120 _asn1_str_cpy (n, sizeof (n), n_start);
121 n_start = NULL;
124 while (p)
126 if ((p->name) && (!strcmp (p->name, n)))
127 break;
128 else
129 p = p->right;
130 } /* while */
132 if (p == NULL)
133 return NULL;
135 else
136 { /* *pointer doesn't have a name */
137 if (n_start[0] == 0)
138 return p;
141 while (n_start)
142 { /* Has the end of NAME been reached? */
143 n_end = strchr (n_start, '.'); /* search the next dot */
144 if (n_end)
146 memcpy (n, n_start, n_end - n_start);
147 n[n_end - n_start] = 0;
148 n_start = n_end;
149 n_start++;
151 else
153 _asn1_str_cpy (n, sizeof (n), n_start);
154 n_start = NULL;
157 if (p->down == NULL)
158 return NULL;
160 p = p->down;
162 /* The identifier "?LAST" indicates the last element
163 in the right chain. */
164 if (!strcmp (n, "?LAST"))
166 if (p == NULL)
167 return NULL;
168 while (p->right)
169 p = p->right;
171 else
172 { /* no "?LAST" */
173 while (p)
175 if ((p->name) && (!strcmp (p->name, n)))
176 break;
177 else
178 p = p->right;
180 if (p == NULL)
181 return NULL;
183 } /* while */
185 return p;
189 /******************************************************************/
190 /* Function : _asn1_set_value */
191 /* Description: sets the field VALUE in a NODE_ASN element. The */
192 /* previous value (if exist) will be lost */
193 /* Parameters: */
194 /* node: element pointer. */
195 /* value: pointer to the value that you want to set. */
196 /* len: character number of value. */
197 /* Return: pointer to the NODE_ASN element. */
198 /******************************************************************/
199 ASN1_TYPE
200 _asn1_set_value (ASN1_TYPE node, const void *value, unsigned int len)
202 if (node == NULL)
203 return node;
204 if (node->value)
206 if (node->value != node->small_value)
207 _asn1_free (node->value);
208 node->value = NULL;
209 node->value_len = 0;
212 if (!len)
213 return node;
215 if (len < sizeof (node->small_value))
217 node->value = node->small_value;
219 else
221 node->value = _asn1_malloc (len);
222 if (node->value == NULL)
223 return NULL;
225 node->value_len = len;
227 memcpy (node->value, value, len);
228 return node;
231 /******************************************************************/
232 /* Function : _asn1_set_value_octet */
233 /* Description: sets the field VALUE in a NODE_ASN element. The */
234 /* previous value (if exist) will be lost. The value */
235 /* given is stored as an octet string. */
236 /* Parameters: */
237 /* node: element pointer. */
238 /* value: pointer to the value that you want to set. */
239 /* len: character number of value. */
240 /* Return: pointer to the NODE_ASN element. */
241 /******************************************************************/
242 ASN1_TYPE
243 _asn1_set_value_octet (ASN1_TYPE node, const void *value, unsigned int len)
245 int len2;
246 void *temp;
248 if (node == NULL)
249 return node;
251 asn1_length_der (len, NULL, &len2);
252 temp = (unsigned char *) _asn1_malloc (len + len2);
253 if (temp == NULL)
254 return NULL;
256 asn1_octet_der (value, len, temp, &len2);
257 return _asn1_set_value_m (node, temp, len2);
260 /* the same as _asn1_set_value except that it sets an already malloc'ed
261 * value.
263 ASN1_TYPE
264 _asn1_set_value_m (ASN1_TYPE node, void *value, unsigned int len)
266 if (node == NULL)
267 return node;
269 if (node->value)
271 if (node->value != node->small_value)
272 _asn1_free (node->value);
273 node->value = NULL;
274 node->value_len = 0;
277 if (!len)
278 return node;
280 node->value = value;
281 node->value_len = len;
283 return node;
286 /******************************************************************/
287 /* Function : _asn1_append_value */
288 /* Description: appends to the field VALUE in a NODE_ASN element. */
289 /* */
290 /* Parameters: */
291 /* node: element pointer. */
292 /* value: pointer to the value that you want to be appended. */
293 /* len: character number of value. */
294 /* Return: pointer to the NODE_ASN element. */
295 /******************************************************************/
296 ASN1_TYPE
297 _asn1_append_value (ASN1_TYPE node, const void *value, unsigned int len)
299 if (node == NULL)
300 return node;
301 if (node->value != NULL && node->value != node->small_value)
303 /* value is allocated */
304 int prev_len = node->value_len;
305 node->value_len += len;
306 node->value = _asn1_realloc (node->value, node->value_len);
307 if (node->value == NULL)
309 node->value_len = 0;
310 return NULL;
312 memcpy (&node->value[prev_len], value, len);
314 return node;
316 else if (node->value == node->small_value)
318 /* value is in node */
319 int prev_len = node->value_len;
320 node->value_len += len;
321 node->value = _asn1_malloc (node->value_len);
322 if (node->value == NULL)
324 node->value_len = 0;
325 return NULL;
327 memcpy (node->value, node->small_value, prev_len);
328 memcpy (&node->value[prev_len], value, len);
330 return node;
332 else /* node->value == NULL */
333 return _asn1_set_value (node, value, len);
336 /******************************************************************/
337 /* Function : _asn1_set_name */
338 /* Description: sets the field NAME in a NODE_ASN element. The */
339 /* previous value (if exist) will be lost */
340 /* Parameters: */
341 /* node: element pointer. */
342 /* name: a null terminated string with the name that you want */
343 /* to set. */
344 /* Return: pointer to the NODE_ASN element. */
345 /******************************************************************/
346 ASN1_TYPE
347 _asn1_set_name (ASN1_TYPE node, const char *name)
349 if (node == NULL)
350 return node;
352 if (node->name)
354 _asn1_free (node->name);
355 node->name = NULL;
358 if (name == NULL)
359 return node;
361 if (strlen (name))
363 node->name = (char *) _asn1_strdup (name);
364 if (node->name == NULL)
365 return NULL;
367 else
368 node->name = NULL;
369 return node;
372 /******************************************************************/
373 /* Function : _asn1_set_right */
374 /* Description: sets the field RIGHT in a NODE_ASN element. */
375 /* Parameters: */
376 /* node: element pointer. */
377 /* right: pointer to a NODE_ASN element that you want be pointed*/
378 /* by NODE. */
379 /* Return: pointer to *NODE. */
380 /******************************************************************/
381 ASN1_TYPE
382 _asn1_set_right (ASN1_TYPE node, ASN1_TYPE right)
384 if (node == NULL)
385 return node;
386 node->right = right;
387 if (right)
388 right->left = node;
389 return node;
392 /******************************************************************/
393 /* Function : _asn1_get_right */
394 /* Description: returns the element pointed by the RIGHT field of */
395 /* a NODE_ASN element. */
396 /* Parameters: */
397 /* node: NODE_ASN element pointer. */
398 /* Return: field RIGHT of NODE. */
399 /******************************************************************/
400 ASN1_TYPE
401 _asn1_get_right (ASN1_TYPE node)
403 if (node == NULL)
404 return NULL;
405 return node->right;
408 /******************************************************************/
409 /* Function : _asn1_get_last_right */
410 /* Description: return the last element along the right chain. */
411 /* Parameters: */
412 /* node: starting element pointer. */
413 /* Return: pointer to the last element along the right chain. */
414 /******************************************************************/
415 ASN1_TYPE
416 _asn1_get_last_right (ASN1_TYPE node)
418 ASN1_TYPE p;
420 if (node == NULL)
421 return NULL;
422 p = node;
423 while (p->right)
424 p = p->right;
425 return p;
428 /******************************************************************/
429 /* Function : _asn1_set_down */
430 /* Description: sets the field DOWN in a NODE_ASN element. */
431 /* Parameters: */
432 /* node: element pointer. */
433 /* down: pointer to a NODE_ASN element that you want be pointed */
434 /* by NODE. */
435 /* Return: pointer to *NODE. */
436 /******************************************************************/
437 ASN1_TYPE
438 _asn1_set_down (ASN1_TYPE node, ASN1_TYPE down)
440 if (node == NULL)
441 return node;
442 node->down = down;
443 if (down)
444 down->left = node;
445 return node;
448 /******************************************************************/
449 /* Function : _asn1_get_down */
450 /* Description: returns the element pointed by the DOWN field of */
451 /* a NODE_ASN element. */
452 /* Parameters: */
453 /* node: NODE_ASN element pointer. */
454 /* Return: field DOWN of NODE. */
455 /******************************************************************/
456 ASN1_TYPE
457 _asn1_get_down (ASN1_TYPE node)
459 if (node == NULL)
460 return NULL;
461 return node->down;
464 /******************************************************************/
465 /* Function : _asn1_get_name */
466 /* Description: returns the name of a NODE_ASN element. */
467 /* Parameters: */
468 /* node: NODE_ASN element pointer. */
469 /* Return: a null terminated string. */
470 /******************************************************************/
471 char *
472 _asn1_get_name (ASN1_TYPE node)
474 if (node == NULL)
475 return NULL;
476 return node->name;
479 /******************************************************************/
480 /* Function : _asn1_mod_type */
481 /* Description: change the field TYPE of an NODE_ASN element. */
482 /* The new value is the old one | (bitwise or) the */
483 /* paramener VALUE. */
484 /* Parameters: */
485 /* node: NODE_ASN element pointer. */
486 /* value: the integer value that must be or-ed with the current */
487 /* value of field TYPE. */
488 /* Return: NODE pointer. */
489 /******************************************************************/
490 ASN1_TYPE
491 _asn1_mod_type (ASN1_TYPE node, unsigned int value)
493 if (node == NULL)
494 return node;
495 node->type |= value;
496 return node;
500 /******************************************************************/
501 /* Function : _asn1_remove_node */
502 /* Description: gets free the memory allocated for an NODE_ASN */
503 /* element (not the elements pointed by it). */
504 /* Parameters: */
505 /* node: NODE_ASN element pointer. */
506 /******************************************************************/
507 void
508 _asn1_remove_node (ASN1_TYPE node)
510 if (node == NULL)
511 return;
513 if (node->name != NULL)
514 _asn1_free (node->name);
515 if (node->value != NULL && node->value != node->small_value)
516 _asn1_free (node->value);
517 _asn1_free (node);
520 /******************************************************************/
521 /* Function : _asn1_find_up */
522 /* Description: return the father of the NODE_ASN element. */
523 /* Parameters: */
524 /* node: NODE_ASN element pointer. */
525 /* Return: Null if not found. */
526 /******************************************************************/
527 ASN1_TYPE
528 _asn1_find_up (ASN1_TYPE node)
530 ASN1_TYPE p;
532 if (node == NULL)
533 return NULL;
535 p = node;
537 while ((p->left != NULL) && (p->left->right == p))
538 p = p->left;
540 return p->left;
543 /******************************************************************/
544 /* Function : _asn1_delete_list */
545 /* Description: deletes the list elements (not the elements */
546 /* pointed by them). */
547 /******************************************************************/
548 void
549 _asn1_delete_list (void)
551 list_type *listElement;
553 while (firstElement)
555 listElement = firstElement;
556 firstElement = firstElement->next;
557 _asn1_free (listElement);
561 /******************************************************************/
562 /* Function : _asn1_delete_list_and nodes */
563 /* Description: deletes the list elements and the elements */
564 /* pointed by them. */
565 /******************************************************************/
566 void
567 _asn1_delete_list_and_nodes (void)
569 list_type *listElement;
571 while (firstElement)
573 listElement = firstElement;
574 firstElement = firstElement->next;
575 _asn1_remove_node (listElement->node);
576 _asn1_free (listElement);
581 char *
582 _asn1_ltostr (long v, char *str)
584 long d, r;
585 char temp[20];
586 int count, k, start;
588 if (v < 0)
590 str[0] = '-';
591 start = 1;
592 v = -v;
594 else
595 start = 0;
597 count = 0;
600 d = v / 10;
601 r = v - d * 10;
602 temp[start + count] = '0' + (char) r;
603 count++;
604 v = d;
606 while (v);
608 for (k = 0; k < count; k++)
609 str[k + start] = temp[start + count - k - 1];
610 str[count + start] = 0;
611 return str;
615 /******************************************************************/
616 /* Function : _asn1_change_integer_value */
617 /* Description: converts into DER coding the value assign to an */
618 /* INTEGER constant. */
619 /* Parameters: */
620 /* node: root of an ASN1element. */
621 /* Return: */
622 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
623 /* otherwise ASN1_SUCCESS */
624 /******************************************************************/
625 asn1_retCode
626 _asn1_change_integer_value (ASN1_TYPE node)
628 ASN1_TYPE p;
629 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
630 unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
631 int len;
633 if (node == NULL)
634 return ASN1_ELEMENT_NOT_FOUND;
636 p = node;
637 while (p)
639 if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
641 if (p->value)
643 _asn1_convert_integer (p->value, val, sizeof (val), &len);
644 asn1_octet_der (val, len, val2, &len);
645 _asn1_set_value (p, val2, len);
649 if (p->down)
651 p = p->down;
653 else
655 if (p == node)
656 p = NULL;
657 else if (p->right)
658 p = p->right;
659 else
661 while (1)
663 p = _asn1_find_up (p);
664 if (p == node)
666 p = NULL;
667 break;
669 if (p->right)
671 p = p->right;
672 break;
679 return ASN1_SUCCESS;
683 /******************************************************************/
684 /* Function : _asn1_expand_object_id */
685 /* Description: expand the IDs of an OBJECT IDENTIFIER constant. */
686 /* Parameters: */
687 /* node: root of an ASN1 element. */
688 /* Return: */
689 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
690 /* otherwise ASN1_SUCCESS */
691 /******************************************************************/
692 asn1_retCode
693 _asn1_expand_object_id (ASN1_TYPE node)
695 ASN1_TYPE p, p2, p3, p4, p5;
696 char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
697 int move, tlen;
699 if (node == NULL)
700 return ASN1_ELEMENT_NOT_FOUND;
702 _asn1_str_cpy (name_root, sizeof (name_root), node->name);
704 p = node;
705 move = DOWN;
707 while (!((p == node) && (move == UP)))
709 if (move != UP)
711 if ((type_field (p->type) == TYPE_OBJECT_ID)
712 && (p->type & CONST_ASSIGN))
714 p2 = p->down;
715 if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
717 if (p2->value && !isdigit (p2->value[0]))
719 _asn1_str_cpy (name2, sizeof (name2), name_root);
720 _asn1_str_cat (name2, sizeof (name2), ".");
721 _asn1_str_cat (name2, sizeof (name2),
722 (char *) p2->value);
723 p3 = asn1_find_node (node, name2);
724 if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
725 !(p3->type & CONST_ASSIGN))
726 return ASN1_ELEMENT_NOT_FOUND;
727 _asn1_set_down (p, p2->right);
728 _asn1_remove_node (p2);
729 p2 = p;
730 p4 = p3->down;
731 while (p4)
733 if (type_field (p4->type) == TYPE_CONSTANT)
735 p5 = _asn1_add_node_only (TYPE_CONSTANT);
736 _asn1_set_name (p5, p4->name);
737 tlen = _asn1_strlen (p4->value);
738 if (tlen > 0)
739 _asn1_set_value (p5, p4->value, tlen + 1);
740 if (p2 == p)
742 _asn1_set_right (p5, p->down);
743 _asn1_set_down (p, p5);
745 else
747 _asn1_set_right (p5, p2->right);
748 _asn1_set_right (p2, p5);
750 p2 = p5;
752 p4 = p4->right;
754 move = DOWN;
755 continue;
759 move = DOWN;
761 else
762 move = RIGHT;
764 if (move == DOWN)
766 if (p->down)
767 p = p->down;
768 else
769 move = RIGHT;
772 if (p == node)
774 move = UP;
775 continue;
778 if (move == RIGHT)
780 if (p->right)
781 p = p->right;
782 else
783 move = UP;
785 if (move == UP)
786 p = _asn1_find_up (p);
790 /*******************************/
791 /* expand DEFAULT */
792 /*******************************/
793 p = node;
794 move = DOWN;
796 while (!((p == node) && (move == UP)))
798 if (move != UP)
800 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
801 (p->type & CONST_DEFAULT))
803 p2 = p->down;
804 if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
806 _asn1_str_cpy (name2, sizeof (name2), name_root);
807 _asn1_str_cat (name2, sizeof (name2), ".");
808 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
809 p3 = asn1_find_node (node, name2);
810 if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
811 !(p3->type & CONST_ASSIGN))
812 return ASN1_ELEMENT_NOT_FOUND;
813 p4 = p3->down;
814 name2[0] = 0;
815 while (p4)
817 if (type_field (p4->type) == TYPE_CONSTANT)
819 if (name2[0])
820 _asn1_str_cat (name2, sizeof (name2), ".");
821 _asn1_str_cat (name2, sizeof (name2),
822 (char *) p4->value);
824 p4 = p4->right;
826 tlen = strlen (name2);
827 if (tlen > 0)
828 _asn1_set_value (p2, name2, tlen + 1);
831 move = DOWN;
833 else
834 move = RIGHT;
836 if (move == DOWN)
838 if (p->down)
839 p = p->down;
840 else
841 move = RIGHT;
844 if (p == node)
846 move = UP;
847 continue;
850 if (move == RIGHT)
852 if (p->right)
853 p = p->right;
854 else
855 move = UP;
857 if (move == UP)
858 p = _asn1_find_up (p);
861 return ASN1_SUCCESS;
865 /******************************************************************/
866 /* Function : _asn1_type_set_config */
867 /* Description: sets the CONST_SET and CONST_NOT_USED properties */
868 /* in the fields of the SET elements. */
869 /* Parameters: */
870 /* node: root of an ASN1 element. */
871 /* Return: */
872 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
873 /* otherwise ASN1_SUCCESS */
874 /******************************************************************/
875 asn1_retCode
876 _asn1_type_set_config (ASN1_TYPE node)
878 ASN1_TYPE p, p2;
879 int move;
881 if (node == NULL)
882 return ASN1_ELEMENT_NOT_FOUND;
884 p = node;
885 move = DOWN;
887 while (!((p == node) && (move == UP)))
889 if (move != UP)
891 if (type_field (p->type) == TYPE_SET)
893 p2 = p->down;
894 while (p2)
896 if (type_field (p2->type) != TYPE_TAG)
897 p2->type |= CONST_SET | CONST_NOT_USED;
898 p2 = p2->right;
901 move = DOWN;
903 else
904 move = RIGHT;
906 if (move == DOWN)
908 if (p->down)
909 p = p->down;
910 else
911 move = RIGHT;
914 if (p == node)
916 move = UP;
917 continue;
920 if (move == RIGHT)
922 if (p->right)
923 p = p->right;
924 else
925 move = UP;
927 if (move == UP)
928 p = _asn1_find_up (p);
931 return ASN1_SUCCESS;
935 /******************************************************************/
936 /* Function : _asn1_check_identifier */
937 /* Description: checks the definitions of all the identifiers */
938 /* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */
939 /* The _asn1_identifierMissing global variable is filled if */
940 /* necessary. */
941 /* Parameters: */
942 /* node: root of an ASN1 element. */
943 /* Return: */
944 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
945 /* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */
946 /* otherwise ASN1_SUCCESS */
947 /******************************************************************/
948 asn1_retCode
949 _asn1_check_identifier (ASN1_TYPE node)
951 ASN1_TYPE p, p2;
952 char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
954 if (node == NULL)
955 return ASN1_ELEMENT_NOT_FOUND;
957 p = node;
958 while (p)
960 if (type_field (p->type) == TYPE_IDENTIFIER)
962 _asn1_str_cpy (name2, sizeof (name2), node->name);
963 _asn1_str_cat (name2, sizeof (name2), ".");
964 _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
965 p2 = asn1_find_node (node, name2);
966 if (p2 == NULL)
968 _asn1_strcpy (_asn1_identifierMissing, p->value);
969 return ASN1_IDENTIFIER_NOT_FOUND;
972 else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
973 (p->type & CONST_DEFAULT))
975 p2 = p->down;
976 if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
978 _asn1_str_cpy (name2, sizeof (name2), node->name);
979 _asn1_str_cat (name2, sizeof (name2), ".");
980 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
981 _asn1_strcpy (_asn1_identifierMissing, p2->value);
982 p2 = asn1_find_node (node, name2);
983 if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
984 !(p2->type & CONST_ASSIGN))
985 return ASN1_IDENTIFIER_NOT_FOUND;
986 else
987 _asn1_identifierMissing[0] = 0;
990 else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
991 (p->type & CONST_ASSIGN))
993 p2 = p->down;
994 if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
996 if (p2->value && !isdigit (p2->value[0]))
998 _asn1_str_cpy (name2, sizeof (name2), node->name);
999 _asn1_str_cat (name2, sizeof (name2), ".");
1000 _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
1001 _asn1_strcpy (_asn1_identifierMissing, p2->value);
1002 p2 = asn1_find_node (node, name2);
1003 if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
1004 !(p2->type & CONST_ASSIGN))
1005 return ASN1_IDENTIFIER_NOT_FOUND;
1006 else
1007 _asn1_identifierMissing[0] = 0;
1012 if (p->down)
1014 p = p->down;
1016 else if (p->right)
1017 p = p->right;
1018 else
1020 while (1)
1022 p = _asn1_find_up (p);
1023 if (p == node)
1025 p = NULL;
1026 break;
1028 if (p->right)
1030 p = p->right;
1031 break;
1037 return ASN1_SUCCESS;
1041 /******************************************************************/
1042 /* Function : _asn1_set_default_tag */
1043 /* Description: sets the default IMPLICIT or EXPLICIT property in */
1044 /* the tagged elements that don't have this declaration. */
1045 /* Parameters: */
1046 /* node: pointer to a DEFINITIONS element. */
1047 /* Return: */
1048 /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */
1049 /* a DEFINITIONS element, */
1050 /* otherwise ASN1_SUCCESS */
1051 /******************************************************************/
1052 asn1_retCode
1053 _asn1_set_default_tag (ASN1_TYPE node)
1055 ASN1_TYPE p;
1057 if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
1058 return ASN1_ELEMENT_NOT_FOUND;
1060 p = node;
1061 while (p)
1063 if ((type_field (p->type) == TYPE_TAG) &&
1064 !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
1066 if (node->type & CONST_EXPLICIT)
1067 p->type |= CONST_EXPLICIT;
1068 else
1069 p->type |= CONST_IMPLICIT;
1072 if (p->down)
1074 p = p->down;
1076 else if (p->right)
1077 p = p->right;
1078 else
1080 while (1)
1082 p = _asn1_find_up (p);
1083 if (p == node)
1085 p = NULL;
1086 break;
1088 if (p->right)
1090 p = p->right;
1091 break;
1097 return ASN1_SUCCESS;