Initialize Tizen 2.3
[external/libtasn1.git] / lib / parser_aux.c
1 /*
2  * Copyright (C) 2000, 2001, 2004, 2006, 2007, 2008, 2009, 2010 Free
3  * Software Foundation, Inc.
4  *
5  * This file is part of LIBTASN1.
6  *
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.
11  *
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.
16  *
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
21  */
22
23 #include <int.h>
24 #include "parser_aux.h"
25 #include "gstr.h"
26 #include "structure.h"
27 #include "element.h"
28
29 char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1];   /* identifier name not found */
30
31 /***********************************************/
32 /* Type: list_type                             */
33 /* Description: type used in the list during   */
34 /* the structure creation.                     */
35 /***********************************************/
36 typedef struct list_struct
37 {
38   ASN1_TYPE node;
39   struct list_struct *next;
40 } list_type;
41
42
43 /* Pointer to the first element of the list */
44 list_type *firstElement = NULL;
45
46 /******************************************************/
47 /* Function : _asn1_add_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 TYPE_         */
52 /*         and CONST_ constants).                     */
53 /* Return: pointer to the new element.                */
54 /******************************************************/
55 ASN1_TYPE
56 _asn1_add_node (unsigned int type)
57 {
58   list_type *listElement;
59   ASN1_TYPE punt;
60
61   punt = (ASN1_TYPE) _asn1_calloc (1, sizeof (struct node_asn_struct));
62   if (punt == NULL)
63     return NULL;
64
65   listElement = (list_type *) _asn1_malloc (sizeof (list_type));
66   if (listElement == NULL)
67     {
68       _asn1_free (punt);
69       return NULL;
70     }
71
72   listElement->node = punt;
73   listElement->next = firstElement;
74   firstElement = listElement;
75
76   punt->type = type;
77
78   return punt;
79 }
80
81 /**
82  * asn1_find_node:
83  * @pointer: NODE_ASN element pointer.
84  * @name: null terminated string with the element's name to find.
85  *
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.
90  *
91  * Returns: the search result, or %NULL if not found.
92  **/
93 ASN1_TYPE
94 asn1_find_node (ASN1_TYPE pointer, const char *name)
95 {
96   ASN1_TYPE p;
97   char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
98   const char *n_start;
99
100   if (pointer == NULL)
101     return NULL;
102
103   if (name == NULL)
104     return NULL;
105
106   p = pointer;
107   n_start = name;
108
109   if (p->name != NULL)
110     {                           /* has *pointer got a name ? */
111       n_end = strchr (n_start, '.');    /* search the first dot */
112       if (n_end)
113         {
114           memcpy (n, n_start, n_end - n_start);
115           n[n_end - n_start] = 0;
116           n_start = n_end;
117           n_start++;
118         }
119       else
120         {
121           _asn1_str_cpy (n, sizeof (n), n_start);
122           n_start = NULL;
123         }
124
125       while (p)
126         {
127           if ((p->name) && (!strcmp (p->name, n)))
128             break;
129           else
130             p = p->right;
131         }                       /* while */
132
133       if (p == NULL)
134         return NULL;
135     }
136   else
137     {                           /* *pointer doesn't have a name */
138       if (n_start[0] == 0)
139         return p;
140     }
141
142   while (n_start)
143     {                           /* Has the end of NAME been reached? */
144       n_end = strchr (n_start, '.');    /* search the next dot */
145       if (n_end)
146         {
147           memcpy (n, n_start, n_end - n_start);
148           n[n_end - n_start] = 0;
149           n_start = n_end;
150           n_start++;
151         }
152       else
153         {
154           _asn1_str_cpy (n, sizeof (n), n_start);
155           n_start = NULL;
156         }
157
158       if (p->down == NULL)
159         return NULL;
160
161       p = p->down;
162
163       /* The identifier "?LAST" indicates the last element
164          in the right chain. */
165       if (!strcmp (n, "?LAST"))
166         {
167           if (p == NULL)
168             return NULL;
169           while (p->right)
170             p = p->right;
171         }
172       else
173         {                       /* no "?LAST" */
174           while (p)
175             {
176               if ((p->name) && (!strcmp (p->name, n)))
177                 break;
178               else
179                 p = p->right;
180             }
181           if (p == NULL)
182             return NULL;
183         }
184     }                           /* while */
185
186   return p;
187 }
188
189
190 /******************************************************************/
191 /* Function : _asn1_set_value                                     */
192 /* Description: sets the field VALUE in a NODE_ASN element. The   */
193 /*              previous value (if exist) will be lost            */
194 /* Parameters:                                                    */
195 /*   node: element pointer.                                       */
196 /*   value: pointer to the value that you want to set.            */
197 /*   len: character number of value.                              */
198 /* Return: pointer to the NODE_ASN element.                       */
199 /******************************************************************/
200 ASN1_TYPE
201 _asn1_set_value (ASN1_TYPE node, const void *value, unsigned int len)
202 {
203   if (node == NULL)
204     return node;
205   if (node->value)
206     {
207       if (node->value != node->small_value)
208         _asn1_free (node->value);
209       node->value = NULL;
210       node->value_len = 0;
211     }
212
213   if (!len)
214     return node;
215
216   if (len < sizeof (node->small_value))
217     {
218       node->value = node->small_value;
219     }
220   else
221     {
222       node->value = _asn1_malloc (len);
223       if (node->value == NULL)
224         return NULL;
225     }
226   node->value_len = len;
227
228   memcpy (node->value, value, len);
229   return node;
230 }
231
232 /******************************************************************/
233 /* Function : _asn1_set_value_octet                               */
234 /* Description: sets the field VALUE in a NODE_ASN element. The   */
235 /*              previous value (if exist) will be lost. The value */
236 /*              given is stored as an octet string.               */
237 /* Parameters:                                                    */
238 /*   node: element pointer.                                       */
239 /*   value: pointer to the value that you want to set.            */
240 /*   len: character number of value.                              */
241 /* Return: pointer to the NODE_ASN element.                       */
242 /******************************************************************/
243 ASN1_TYPE
244 _asn1_set_value_octet (ASN1_TYPE node, const void *value, unsigned int len)
245 {
246   int len2;
247   void *temp;
248
249   if (node == NULL)
250     return node;
251
252   asn1_length_der (len, NULL, &len2);
253   temp = (unsigned char *) _asn1_malloc (len + len2);
254   if (temp == NULL)
255     return NULL;
256
257   asn1_octet_der (value, len, temp, &len2);
258   return _asn1_set_value_m (node, temp, len2);
259 }
260
261 /* the same as _asn1_set_value except that it sets an already malloc'ed
262  * value.
263  */
264 ASN1_TYPE
265 _asn1_set_value_m (ASN1_TYPE node, void *value, unsigned int len)
266 {
267   if (node == NULL)
268     return node;
269
270   if (node->value)
271     {
272       if (node->value != node->small_value)
273         _asn1_free (node->value);
274       node->value = NULL;
275       node->value_len = 0;
276     }
277
278   if (!len)
279     return node;
280
281   node->value = value;
282   node->value_len = len;
283
284   return node;
285 }
286
287 /******************************************************************/
288 /* Function : _asn1_append_value                                  */
289 /* Description: appends to the field VALUE in a NODE_ASN element. */
290 /*                                                                */
291 /* Parameters:                                                    */
292 /*   node: element pointer.                                       */
293 /*   value: pointer to the value that you want to be appended.    */
294 /*   len: character number of value.                              */
295 /* Return: pointer to the NODE_ASN element.                       */
296 /******************************************************************/
297 ASN1_TYPE
298 _asn1_append_value (ASN1_TYPE node, const void *value, unsigned int len)
299 {
300   if (node == NULL)
301     return node;
302   if (node->value != NULL && node->value != node->small_value)
303     {
304       /* value is allocated */
305       int prev_len = node->value_len;
306       node->value_len += len;
307       node->value = _asn1_realloc (node->value, node->value_len);
308       if (node->value == NULL)
309         {
310           node->value_len = 0;
311           return NULL;
312         }
313       memcpy (&node->value[prev_len], value, len);
314
315       return node;
316     }
317   else if (node->value == node->small_value)
318     {
319       /* value is in node */
320       int prev_len = node->value_len;
321       node->value_len += len;
322       node->value = _asn1_malloc (node->value_len);
323       if (node->value == NULL)
324         {
325           node->value_len = 0;
326           return NULL;
327         }
328       memcpy (node->value, node->small_value, prev_len);
329       memcpy (&node->value[prev_len], value, len);
330
331       return node;
332     }
333   else                          /* node->value == NULL */
334     return _asn1_set_value (node, value, len);
335 }
336
337 /******************************************************************/
338 /* Function : _asn1_set_name                                      */
339 /* Description: sets the field NAME in a NODE_ASN element. The    */
340 /*              previous value (if exist) will be lost            */
341 /* Parameters:                                                    */
342 /*   node: element pointer.                                       */
343 /*   name: a null terminated string with the name that you want   */
344 /*         to set.                                                */
345 /* Return: pointer to the NODE_ASN element.                       */
346 /******************************************************************/
347 ASN1_TYPE
348 _asn1_set_name (ASN1_TYPE node, const char *name)
349 {
350   if (node == NULL)
351     return node;
352
353   if (node->name)
354     {
355       _asn1_free (node->name);
356       node->name = NULL;
357     }
358
359   if (name == NULL)
360     return node;
361
362   if (strlen (name))
363     {
364       node->name = (char *) _asn1_strdup (name);
365       if (node->name == NULL)
366         return NULL;
367     }
368   else
369     node->name = NULL;
370   return node;
371 }
372
373 /******************************************************************/
374 /* Function : _asn1_set_right                                     */
375 /* Description: sets the field RIGHT in a NODE_ASN element.       */
376 /* Parameters:                                                    */
377 /*   node: element pointer.                                       */
378 /*   right: pointer to a NODE_ASN element that you want be pointed*/
379 /*          by NODE.                                              */
380 /* Return: pointer to *NODE.                                      */
381 /******************************************************************/
382 ASN1_TYPE
383 _asn1_set_right (ASN1_TYPE node, ASN1_TYPE right)
384 {
385   if (node == NULL)
386     return node;
387   node->right = right;
388   if (right)
389     right->left = node;
390   return node;
391 }
392
393 /******************************************************************/
394 /* Function : _asn1_get_right                                     */
395 /* Description: returns the element pointed by the RIGHT field of */
396 /*              a NODE_ASN element.                               */
397 /* Parameters:                                                    */
398 /*   node: NODE_ASN element pointer.                              */
399 /* Return: field RIGHT of NODE.                                   */
400 /******************************************************************/
401 ASN1_TYPE
402 _asn1_get_right (ASN1_TYPE node)
403 {
404   if (node == NULL)
405     return NULL;
406   return node->right;
407 }
408
409 /******************************************************************/
410 /* Function : _asn1_get_last_right                                */
411 /* Description: return the last element along the right chain.    */
412 /* Parameters:                                                    */
413 /*   node: starting element pointer.                              */
414 /* Return: pointer to the last element along the right chain.     */
415 /******************************************************************/
416 ASN1_TYPE
417 _asn1_get_last_right (ASN1_TYPE node)
418 {
419   ASN1_TYPE p;
420
421   if (node == NULL)
422     return NULL;
423   p = node;
424   while (p->right)
425     p = p->right;
426   return p;
427 }
428
429 /******************************************************************/
430 /* Function : _asn1_set_down                                      */
431 /* Description: sets the field DOWN in a NODE_ASN element.        */
432 /* Parameters:                                                    */
433 /*   node: element pointer.                                       */
434 /*   down: pointer to a NODE_ASN element that you want be pointed */
435 /*          by NODE.                                              */
436 /* Return: pointer to *NODE.                                      */
437 /******************************************************************/
438 ASN1_TYPE
439 _asn1_set_down (ASN1_TYPE node, ASN1_TYPE down)
440 {
441   if (node == NULL)
442     return node;
443   node->down = down;
444   if (down)
445     down->left = node;
446   return node;
447 }
448
449 /******************************************************************/
450 /* Function : _asn1_get_down                                      */
451 /* Description: returns the element pointed by the DOWN field of  */
452 /*              a NODE_ASN element.                               */
453 /* Parameters:                                                    */
454 /*   node: NODE_ASN element pointer.                              */
455 /* Return: field DOWN of NODE.                                    */
456 /******************************************************************/
457 ASN1_TYPE
458 _asn1_get_down (ASN1_TYPE node)
459 {
460   if (node == NULL)
461     return NULL;
462   return node->down;
463 }
464
465 /******************************************************************/
466 /* Function : _asn1_get_name                                      */
467 /* Description: returns the name of a NODE_ASN element.           */
468 /* Parameters:                                                    */
469 /*   node: NODE_ASN element pointer.                              */
470 /* Return: a null terminated string.                              */
471 /******************************************************************/
472 char *
473 _asn1_get_name (ASN1_TYPE node)
474 {
475   if (node == NULL)
476     return NULL;
477   return node->name;
478 }
479
480 /******************************************************************/
481 /* Function : _asn1_mod_type                                      */
482 /* Description: change the field TYPE of an NODE_ASN element.     */
483 /*              The new value is the old one | (bitwise or) the   */
484 /*              paramener VALUE.                                  */
485 /* Parameters:                                                    */
486 /*   node: NODE_ASN element pointer.                              */
487 /*   value: the integer value that must be or-ed with the current */
488 /*          value of field TYPE.                                  */
489 /* Return: NODE pointer.                                          */
490 /******************************************************************/
491 ASN1_TYPE
492 _asn1_mod_type (ASN1_TYPE node, unsigned int value)
493 {
494   if (node == NULL)
495     return node;
496   node->type |= value;
497   return node;
498 }
499
500
501 /******************************************************************/
502 /* Function : _asn1_remove_node                                   */
503 /* Description: gets free the memory allocated for an NODE_ASN    */
504 /*              element (not the elements pointed by it).         */
505 /* Parameters:                                                    */
506 /*   node: NODE_ASN element pointer.                              */
507 /******************************************************************/
508 void
509 _asn1_remove_node (ASN1_TYPE node)
510 {
511   if (node == NULL)
512     return;
513
514   if (node->name != NULL)
515     _asn1_free (node->name);
516   if (node->value != NULL && node->value != node->small_value)
517     _asn1_free (node->value);
518   _asn1_free (node);
519 }
520
521 /******************************************************************/
522 /* Function : _asn1_find_up                                       */
523 /* Description: return the father of the NODE_ASN element.        */
524 /* Parameters:                                                    */
525 /*   node: NODE_ASN element pointer.                              */
526 /* Return: Null if not found.                                     */
527 /******************************************************************/
528 ASN1_TYPE
529 _asn1_find_up (ASN1_TYPE node)
530 {
531   ASN1_TYPE p;
532
533   if (node == NULL)
534     return NULL;
535
536   p = node;
537
538   while ((p->left != NULL) && (p->left->right == p))
539     p = p->left;
540
541   return p->left;
542 }
543
544 /******************************************************************/
545 /* Function : _asn1_delete_list                                   */
546 /* Description: deletes the list elements (not the elements       */
547 /*  pointed by them).                                             */
548 /******************************************************************/
549 void
550 _asn1_delete_list (void)
551 {
552   list_type *listElement;
553
554   while (firstElement)
555     {
556       listElement = firstElement;
557       firstElement = firstElement->next;
558       _asn1_free (listElement);
559     }
560 }
561
562 /******************************************************************/
563 /* Function : _asn1_delete_list_and nodes                         */
564 /* Description: deletes the list elements and the elements        */
565 /*  pointed by them.                                              */
566 /******************************************************************/
567 void
568 _asn1_delete_list_and_nodes (void)
569 {
570   list_type *listElement;
571
572   while (firstElement)
573     {
574       listElement = firstElement;
575       firstElement = firstElement->next;
576       _asn1_remove_node (listElement->node);
577       _asn1_free (listElement);
578     }
579 }
580
581
582 char *
583 _asn1_ltostr (long v, char *str)
584 {
585   long d, r;
586   char temp[20];
587   int count, k, start;
588
589   if (v < 0)
590     {
591       str[0] = '-';
592       start = 1;
593       v = -v;
594     }
595   else
596     start = 0;
597
598   count = 0;
599   do
600     {
601       d = v / 10;
602       r = v - d * 10;
603       temp[start + count] = '0' + (char) r;
604       count++;
605       v = d;
606     }
607   while (v);
608
609   for (k = 0; k < count; k++)
610     str[k + start] = temp[start + count - k - 1];
611   str[count + start] = 0;
612   return str;
613 }
614
615
616 /******************************************************************/
617 /* Function : _asn1_change_integer_value                          */
618 /* Description: converts into DER coding the value assign to an   */
619 /*   INTEGER constant.                                            */
620 /* Parameters:                                                    */
621 /*   node: root of an ASN1element.                                */
622 /* Return:                                                        */
623 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
624 /*   otherwise ASN1_SUCCESS                                             */
625 /******************************************************************/
626 asn1_retCode
627 _asn1_change_integer_value (ASN1_TYPE node)
628 {
629   ASN1_TYPE p;
630   unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
631   unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
632   int len;
633
634   if (node == NULL)
635     return ASN1_ELEMENT_NOT_FOUND;
636
637   p = node;
638   while (p)
639     {
640       if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
641         {
642           if (p->value)
643             {
644               _asn1_convert_integer (p->value, val, sizeof (val), &len);
645               asn1_octet_der (val, len, val2, &len);
646               _asn1_set_value (p, val2, len);
647             }
648         }
649
650       if (p->down)
651         {
652           p = p->down;
653         }
654       else
655         {
656           if (p == node)
657             p = NULL;
658           else if (p->right)
659             p = p->right;
660           else
661             {
662               while (1)
663                 {
664                   p = _asn1_find_up (p);
665                   if (p == node)
666                     {
667                       p = NULL;
668                       break;
669                     }
670                   if (p->right)
671                     {
672                       p = p->right;
673                       break;
674                     }
675                 }
676             }
677         }
678     }
679
680   return ASN1_SUCCESS;
681 }
682
683
684 /******************************************************************/
685 /* Function : _asn1_expand_object_id                              */
686 /* Description: expand the IDs of an OBJECT IDENTIFIER constant.  */
687 /* Parameters:                                                    */
688 /*   node: root of an ASN1 element.                               */
689 /* Return:                                                        */
690 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
691 /*   otherwise ASN1_SUCCESS                                             */
692 /******************************************************************/
693 asn1_retCode
694 _asn1_expand_object_id (ASN1_TYPE node)
695 {
696   ASN1_TYPE p, p2, p3, p4, p5;
697   char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
698   int move, tlen;
699
700   if (node == NULL)
701     return ASN1_ELEMENT_NOT_FOUND;
702
703   _asn1_str_cpy (name_root, sizeof (name_root), node->name);
704
705   p = node;
706   move = DOWN;
707
708   while (!((p == node) && (move == UP)))
709     {
710       if (move != UP)
711         {
712           if ((type_field (p->type) == TYPE_OBJECT_ID)
713               && (p->type & CONST_ASSIGN))
714             {
715               p2 = p->down;
716               if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
717                 {
718                   if (p2->value && !isdigit (p2->value[0]))
719                     {
720                       _asn1_str_cpy (name2, sizeof (name2), name_root);
721                       _asn1_str_cat (name2, sizeof (name2), ".");
722                       _asn1_str_cat (name2, sizeof (name2), 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)
732                         {
733                           if (type_field (p4->type) == TYPE_CONSTANT)
734                             {
735                               p5 = _asn1_add_node_only (TYPE_CONSTANT);
736                               _asn1_set_name (p5, p4->name);
737                               tlen = strlen (p4->value);
738                               if (tlen > 0)
739                                 _asn1_set_value (p5, p4->value, tlen + 1);
740                               if (p2 == p)
741                                 {
742                                   _asn1_set_right (p5, p->down);
743                                   _asn1_set_down (p, p5);
744                                 }
745                               else
746                                 {
747                                   _asn1_set_right (p5, p2->right);
748                                   _asn1_set_right (p2, p5);
749                                 }
750                               p2 = p5;
751                             }
752                           p4 = p4->right;
753                         }
754                       move = DOWN;
755                       continue;
756                     }
757                 }
758             }
759           move = DOWN;
760         }
761       else
762         move = RIGHT;
763
764       if (move == DOWN)
765         {
766           if (p->down)
767             p = p->down;
768           else
769             move = RIGHT;
770         }
771
772       if (p == node)
773         {
774           move = UP;
775           continue;
776         }
777
778       if (move == RIGHT)
779         {
780           if (p->right)
781             p = p->right;
782           else
783             move = UP;
784         }
785       if (move == UP)
786         p = _asn1_find_up (p);
787     }
788
789
790   /*******************************/
791   /*       expand DEFAULT        */
792   /*******************************/
793   p = node;
794   move = DOWN;
795
796   while (!((p == node) && (move == UP)))
797     {
798       if (move != UP)
799         {
800           if ((type_field (p->type) == TYPE_OBJECT_ID) &&
801               (p->type & CONST_DEFAULT))
802             {
803               p2 = p->down;
804               if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
805                 {
806                   _asn1_str_cpy (name2, sizeof (name2), name_root);
807                   _asn1_str_cat (name2, sizeof (name2), ".");
808                   _asn1_str_cat (name2, sizeof (name2), 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)
816                     {
817                       if (type_field (p4->type) == TYPE_CONSTANT)
818                         {
819                           if (name2[0])
820                             _asn1_str_cat (name2, sizeof (name2), ".");
821                           _asn1_str_cat (name2, sizeof (name2), p4->value);
822                         }
823                       p4 = p4->right;
824                     }
825                   tlen = strlen (name2);
826                   if (tlen > 0)
827                     _asn1_set_value (p2, name2, tlen + 1);
828                 }
829             }
830           move = DOWN;
831         }
832       else
833         move = RIGHT;
834
835       if (move == DOWN)
836         {
837           if (p->down)
838             p = p->down;
839           else
840             move = RIGHT;
841         }
842
843       if (p == node)
844         {
845           move = UP;
846           continue;
847         }
848
849       if (move == RIGHT)
850         {
851           if (p->right)
852             p = p->right;
853           else
854             move = UP;
855         }
856       if (move == UP)
857         p = _asn1_find_up (p);
858     }
859
860   return ASN1_SUCCESS;
861 }
862
863
864 /******************************************************************/
865 /* Function : _asn1_type_set_config                               */
866 /* Description: sets the CONST_SET and CONST_NOT_USED properties  */
867 /*   in the fields of the SET elements.                           */
868 /* Parameters:                                                    */
869 /*   node: root of an ASN1 element.                               */
870 /* Return:                                                        */
871 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL,                       */
872 /*   otherwise ASN1_SUCCESS                                             */
873 /******************************************************************/
874 asn1_retCode
875 _asn1_type_set_config (ASN1_TYPE node)
876 {
877   ASN1_TYPE p, p2;
878   int move;
879
880   if (node == NULL)
881     return ASN1_ELEMENT_NOT_FOUND;
882
883   p = node;
884   move = DOWN;
885
886   while (!((p == node) && (move == UP)))
887     {
888       if (move != UP)
889         {
890           if (type_field (p->type) == TYPE_SET)
891             {
892               p2 = p->down;
893               while (p2)
894                 {
895                   if (type_field (p2->type) != TYPE_TAG)
896                     p2->type |= CONST_SET | CONST_NOT_USED;
897                   p2 = p2->right;
898                 }
899             }
900           move = DOWN;
901         }
902       else
903         move = RIGHT;
904
905       if (move == DOWN)
906         {
907           if (p->down)
908             p = p->down;
909           else
910             move = RIGHT;
911         }
912
913       if (p == node)
914         {
915           move = UP;
916           continue;
917         }
918
919       if (move == RIGHT)
920         {
921           if (p->right)
922             p = p->right;
923           else
924             move = UP;
925         }
926       if (move == UP)
927         p = _asn1_find_up (p);
928     }
929
930   return ASN1_SUCCESS;
931 }
932
933
934 /******************************************************************/
935 /* Function : _asn1_check_identifier                              */
936 /* Description: checks the definitions of all the identifiers     */
937 /*   and the first element of an OBJECT_ID (e.g. {pkix 0 4}).     */
938 /*   The _asn1_identifierMissing global variable is filled if     */
939 /*   necessary.                                                   */
940 /* Parameters:                                                    */
941 /*   node: root of an ASN1 element.                               */
942 /* Return:                                                        */
943 /*   ASN1_ELEMENT_NOT_FOUND      if NODE is NULL,                 */
944 /*   ASN1_IDENTIFIER_NOT_FOUND   if an identifier is not defined, */
945 /*   otherwise ASN1_SUCCESS                                       */
946 /******************************************************************/
947 asn1_retCode
948 _asn1_check_identifier (ASN1_TYPE node)
949 {
950   ASN1_TYPE p, p2;
951   char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
952
953   if (node == NULL)
954     return ASN1_ELEMENT_NOT_FOUND;
955
956   p = node;
957   while (p)
958     {
959       if (type_field (p->type) == TYPE_IDENTIFIER)
960         {
961           _asn1_str_cpy (name2, sizeof (name2), node->name);
962           _asn1_str_cat (name2, sizeof (name2), ".");
963           _asn1_str_cat (name2, sizeof (name2), p->value);
964           p2 = asn1_find_node (node, name2);
965           if (p2 == NULL)
966             {
967               strcpy (_asn1_identifierMissing, p->value);
968               return ASN1_IDENTIFIER_NOT_FOUND;
969             }
970         }
971       else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
972                (p->type & CONST_DEFAULT))
973         {
974           p2 = p->down;
975           if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
976             {
977               _asn1_str_cpy (name2, sizeof (name2), node->name);
978               _asn1_str_cat (name2, sizeof (name2), ".");
979               _asn1_str_cat (name2, sizeof (name2), p2->value);
980               strcpy (_asn1_identifierMissing, p2->value);
981               p2 = asn1_find_node (node, name2);
982               if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
983                   !(p2->type & CONST_ASSIGN))
984                 return ASN1_IDENTIFIER_NOT_FOUND;
985               else
986                 _asn1_identifierMissing[0] = 0;
987             }
988         }
989       else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
990                (p->type & CONST_ASSIGN))
991         {
992           p2 = p->down;
993           if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
994             {
995               if (p2->value && !isdigit (p2->value[0]))
996                 {
997                   _asn1_str_cpy (name2, sizeof (name2), node->name);
998                   _asn1_str_cat (name2, sizeof (name2), ".");
999                   _asn1_str_cat (name2, sizeof (name2), p2->value);
1000                   strcpy (_asn1_identifierMissing, p2->value);
1001                   p2 = asn1_find_node (node, name2);
1002                   if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
1003                       !(p2->type & CONST_ASSIGN))
1004                     return ASN1_IDENTIFIER_NOT_FOUND;
1005                   else
1006                     _asn1_identifierMissing[0] = 0;
1007                 }
1008             }
1009         }
1010
1011       if (p->down)
1012         {
1013           p = p->down;
1014         }
1015       else if (p->right)
1016         p = p->right;
1017       else
1018         {
1019           while (1)
1020             {
1021               p = _asn1_find_up (p);
1022               if (p == node)
1023                 {
1024                   p = NULL;
1025                   break;
1026                 }
1027               if (p->right)
1028                 {
1029                   p = p->right;
1030                   break;
1031                 }
1032             }
1033         }
1034     }
1035
1036   return ASN1_SUCCESS;
1037 }
1038
1039
1040 /******************************************************************/
1041 /* Function : _asn1_set_default_tag                               */
1042 /* Description: sets the default IMPLICIT or EXPLICIT property in */
1043 /*   the tagged elements that don't have this declaration.        */
1044 /* Parameters:                                                    */
1045 /*   node: pointer to a DEFINITIONS element.                      */
1046 /* Return:                                                        */
1047 /*   ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to   */
1048 /*     a DEFINITIONS element,                                     */
1049 /*   otherwise ASN1_SUCCESS                                       */
1050 /******************************************************************/
1051 asn1_retCode
1052 _asn1_set_default_tag (ASN1_TYPE node)
1053 {
1054   ASN1_TYPE p;
1055
1056   if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
1057     return ASN1_ELEMENT_NOT_FOUND;
1058
1059   p = node;
1060   while (p)
1061     {
1062       if ((type_field (p->type) == TYPE_TAG) &&
1063           !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
1064         {
1065           if (node->type & CONST_EXPLICIT)
1066             p->type |= CONST_EXPLICIT;
1067           else
1068             p->type |= CONST_IMPLICIT;
1069         }
1070
1071       if (p->down)
1072         {
1073           p = p->down;
1074         }
1075       else if (p->right)
1076         p = p->right;
1077       else
1078         {
1079           while (1)
1080             {
1081               p = _asn1_find_up (p);
1082               if (p == node)
1083                 {
1084                   p = NULL;
1085                   break;
1086                 }
1087               if (p->right)
1088                 {
1089                   p = p->right;
1090                   break;
1091                 }
1092             }
1093         }
1094     }
1095
1096   return ASN1_SUCCESS;
1097 }