Fix typo.
[shishi.git] / asn1 / structure.c
blob1291a00981820e9750e08b89be041e3f1bb82b26
1 /*
2 * Copyright (C) 2002 Fabio Fiorina
4 * This file is part of LIBASN1.
6 * The LIBTASN1 library is free software; you can redistribute it and/or
7 * 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,
12 * but 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /*****************************************************/
23 /* File: structure.c */
24 /* Description: Functions to create and delete an */
25 /* ASN1 tree. */
26 /*****************************************************/
29 #include <int.h>
30 #include <errors.h>
31 #include <structure.h>
32 #include "parser_aux.h"
33 #include "der.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 node_asn *
49 _asn1_add_node_only(unsigned int type)
51 node_asn *punt;
53 punt=(node_asn *) _asn1_malloc(sizeof(node_asn));
54 if (punt==NULL) return NULL;
56 punt->left=NULL;
57 punt->name=NULL;
58 punt->type=type;
59 punt->value=NULL;
60 punt->down=NULL;
61 punt->right=NULL;
63 return punt;
67 /******************************************************************/
68 /* Function : _asn1_find_left */
69 /* Description: returns the NODE_ASN element with RIGHT field that*/
70 /* points the element NODE. */
71 /* Parameters: */
72 /* node: NODE_ASN element pointer. */
73 /* Return: NULL if not found. */
74 /******************************************************************/
75 node_asn *
76 _asn1_find_left(node_asn *node)
78 if((node==NULL) || (node->left==NULL) ||
79 (node->left->down==node)) return NULL;
81 return node->left;
85 asn1_retCode
86 _asn1_create_static_structure(ASN1_TYPE pointer,char* output_file_name,char *vector_name)
88 FILE *file;
89 node_asn *p;
90 unsigned long t;
92 file=fopen( output_file_name,"w");
94 if(file==NULL) return ASN1_FILE_NOT_FOUND;
96 fprintf(file,"\n#include \"libtasn1.h\"\n\n");
97 fprintf(file,"const ASN1_ARRAY_TYPE %s[]={\n",vector_name);
99 p=pointer;
101 while(p){
102 fprintf(file," {");
104 if(p->name) fprintf(file,"\"%s\",",p->name);
105 else fprintf(file,"0,");
107 t=p->type;
108 if(p->down) t|=CONST_DOWN;
109 if(p->right) t|=CONST_RIGHT;
111 fprintf(file,"%lu,",t);
113 if(p->value) fprintf(file,"\"%s\"},\n",p->value);
114 else fprintf(file,"0},\n");
116 if(p->down){
117 p=p->down;
119 else if(p->right){
120 p=p->right;
122 else{
123 while(1){
124 p=_asn1_find_up(p);
125 if(p==pointer){
126 p=NULL;
127 break;
129 if(p->right){
130 p=p->right;
131 break;
137 fprintf(file," {0,0,0}\n};\n");
139 fclose(file);
141 return ASN1_SUCCESS;
146 * asn1_array2tree - Creates the structures needed to manage the ASN1 definitions.
147 * @array: specify the array that contains ASN.1 declarations
148 * @definitions: return the pointer to the structure created by *ARRAY ASN.1 declarations
149 * @errorDescription : return the error description.
150 * Description:
152 * Creates the structures needed to manage the ASN1 definitions. ARRAY is a vector created by
153 * 'asn1_parser_asn1_file_c' function.
155 * Returns:
157 * ASN1_SUCCESS\: structure created correctly.
159 * ASN1_ELEMENT_NOT_EMPTY\: *DEFINITIONS not ASN1_TYPE_EMPTY
161 * ASN1_IDENTIFIER_NOT_FOUND\: in the file there is an identifier that is not defined (see ERRORDESCRIPTION for more information).
163 * ASN1_ARRAY_ERROR\: the array pointed by ARRAY is wrong.
165 asn1_retCode
166 asn1_array2tree(const ASN1_ARRAY_TYPE *array,ASN1_TYPE *definitions,
167 char *errorDescription)
169 node_asn *p,*p_last=NULL;
170 unsigned long k;
171 int move;
172 asn1_retCode result;
175 if(*definitions != ASN1_TYPE_EMPTY)
176 return ASN1_ELEMENT_NOT_EMPTY;
178 move=UP;
180 k=0;
181 while(array[k].value || array[k].type || array[k].name){
182 p=_asn1_add_node(array[k].type&(~CONST_DOWN));
183 if(array[k].name) _asn1_set_name(p,array[k].name);
184 if(array[k].value) _asn1_set_value(p,array[k].value,
185 strlen(array[k].value)+1);
187 if(*definitions==NULL) *definitions=p;
189 if(move==DOWN) _asn1_set_down(p_last,p);
190 else if(move==RIGHT) _asn1_set_right(p_last,p);
192 p_last=p;
194 if(array[k].type&CONST_DOWN) move=DOWN;
195 else if(array[k].type&CONST_RIGHT) move=RIGHT;
196 else{
197 while(1){
198 if(p_last==*definitions) break;
200 p_last= _asn1_find_up(p_last);
202 if(p_last==NULL) break;
204 if(p_last->type&CONST_RIGHT){
205 p_last->type&=~CONST_RIGHT;
206 move=RIGHT;
207 break;
209 } /* while */
211 k++;
212 } /* while */
214 if(p_last==*definitions){
215 result=_asn1_check_identifier(*definitions);
216 if(result==ASN1_SUCCESS){
217 _asn1_change_integer_value(*definitions);
218 _asn1_expand_object_id(*definitions);
221 else{
222 result=ASN1_ARRAY_ERROR;
225 if (errorDescription!=NULL) {
226 if(result==ASN1_IDENTIFIER_NOT_FOUND) {
227 Estrcpy(errorDescription,":: identifier '");
228 Estrcat(errorDescription,_asn1_identifierMissing);
229 Estrcat(errorDescription,"' not found");
231 else
232 errorDescription[0]=0;
235 if(result != ASN1_SUCCESS){
236 _asn1_delete_list_and_nodes();
237 *definitions=ASN1_TYPE_EMPTY;
239 else
240 _asn1_delete_list();
242 return result;
247 * asn1_delete_structure - Deletes the structure pointed by *ROOT.
248 * @structure: pointer to the structure that you want to delete.
249 * Description:
251 * Deletes the structure *ROOT.
252 * At the end *ROOT is setted to ASN1_TYPE_EMPTY.
254 * Returns:
256 * ASN1_SUCCESS\: everything OK
258 * ASN1_ELEMENT_NOT_FOUND\: *root==ASN1_TYPE_EMPTY.
261 asn1_retCode
262 asn1_delete_structure(ASN1_TYPE *structure)
264 node_asn *p,*p2,*p3;
266 if(*structure==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
268 p=*structure;
269 while(p){
270 if(p->down){
271 p=p->down;
273 else{ /* no down */
274 p2=p->right;
275 if(p!=*structure){
276 p3=_asn1_find_up(p);
277 _asn1_set_down(p3,p2);
278 _asn1_remove_node(p);
279 p=p3;
281 else{ /* p==root */
282 p3=_asn1_find_left(p);
283 if(!p3){
284 p3=_asn1_find_up(p);
285 if(p3) _asn1_set_down(p3,p2);
286 else{
287 if(p->right) p->right->left=NULL;
290 else _asn1_set_right(p3,p2);
291 _asn1_remove_node(p);
292 p=NULL;
297 *structure=ASN1_TYPE_EMPTY;
298 return ASN1_SUCCESS;
303 node_asn *
304 _asn1_copy_structure3(node_asn *source_node)
306 node_asn *dest_node,*p_s,*p_d,*p_d_prev;
307 int len,len2,move;
309 if(source_node==NULL) return NULL;
311 dest_node=_asn1_add_node_only(source_node->type);
313 p_s=source_node;
314 p_d=dest_node;
316 move=DOWN;
319 if(move!=UP){
320 if(p_s->name) _asn1_set_name(p_d,p_s->name);
321 if(p_s->value){
322 switch(type_field(p_s->type)){
323 case TYPE_OCTET_STRING: case TYPE_BIT_STRING: case TYPE_GENERALSTRING:
324 case TYPE_INTEGER:
325 len2=-1;
326 len=_asn1_get_length_der(p_s->value,&len2);
327 _asn1_set_value(p_d,p_s->value,len+len2);
328 break;
329 default:
330 _asn1_set_value(p_d,p_s->value,strlen(p_s->value)+1);
333 move=DOWN;
335 else move=RIGHT;
337 if(move==DOWN){
338 if(p_s->down){
339 p_s=p_s->down;
340 p_d_prev=p_d;
341 p_d=_asn1_add_node_only(p_s->type);
342 _asn1_set_down(p_d_prev,p_d);
344 else move=RIGHT;
347 if(p_s==source_node) break;
349 if(move==RIGHT){
350 if(p_s->right){
351 p_s=p_s->right;
352 p_d_prev=p_d;
353 p_d=_asn1_add_node_only(p_s->type);
354 _asn1_set_right(p_d_prev,p_d);
356 else move=UP;
358 if(move==UP){
359 p_s=_asn1_find_up(p_s);
360 p_d=_asn1_find_up(p_d);
362 }while(p_s!=source_node);
364 return dest_node;
368 node_asn *
369 _asn1_copy_structure2(node_asn *root,const char *source_name)
371 node_asn *source_node;
373 source_node=_asn1_find_node(root,source_name);
375 return _asn1_copy_structure3(source_node);
380 asn1_retCode
381 _asn1_type_choice_config(node_asn *node)
383 node_asn *p,*p2,*p3,*p4;
384 int move;
386 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
388 p=node;
389 move=DOWN;
391 while(!((p==node) && (move==UP))){
392 if(move!=UP){
393 if((type_field(p->type)==TYPE_CHOICE) &&
394 (p->type&CONST_TAG)){
395 p2=p->down;
396 while(p2){
397 if(type_field(p2->type)!=TYPE_TAG){
398 p2->type|=CONST_TAG;
399 p3=_asn1_find_left(p2);
400 while(p3){
401 if(type_field(p3->type)==TYPE_TAG){
402 p4=_asn1_add_node_only(p3->type);
403 _asn1_set_value(p4,p3->value,strlen(p3->value)+1);
404 _asn1_set_right(p4,p2->down);
405 _asn1_set_down(p2,p4);
407 p3=_asn1_find_left(p3);
410 p2=p2->right;
412 p->type&=~(CONST_TAG);
413 p2=p->down;
414 while(p2){
415 p3=p2->right;
416 if(type_field(p2->type)==TYPE_TAG) asn1_delete_structure(&p2);
417 p2=p3;
420 move=DOWN;
422 else move=RIGHT;
424 if(move==DOWN){
425 if(p->down) p=p->down;
426 else move=RIGHT;
429 if(p==node) {move=UP; continue;}
431 if(move==RIGHT){
432 if(p->right) p=p->right;
433 else move=UP;
435 if(move==UP) p=_asn1_find_up(p);
438 return ASN1_SUCCESS;
442 asn1_retCode
443 _asn1_expand_identifier(node_asn **node,node_asn *root)
445 node_asn *p,*p2,*p3;
446 char name2[MAX_NAME_SIZE+2];
447 int move;
449 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
451 p=*node;
452 move=DOWN;
454 while(!((p==*node) && (move==UP))){
455 if(move!=UP){
456 if(type_field(p->type)==TYPE_IDENTIFIER){
457 _asn1_str_cpy(name2, sizeof(name2), root->name);
458 _asn1_str_cat(name2, sizeof(name2), ".");
459 _asn1_str_cat(name2, sizeof(name2), p->value);
460 p2=_asn1_copy_structure2(root,name2);
461 if(p2==NULL){
462 return ASN1_IDENTIFIER_NOT_FOUND;
464 _asn1_set_name(p2,p->name);
465 p2->right=p->right;
466 p2->left=p->left;
467 if(p->right) p->right->left=p2;
468 p3=p->down;
469 if(p3){
470 while(p3->right) p3=p3->right;
471 _asn1_set_right(p3,p2->down);
472 _asn1_set_down(p2,p->down);
475 p3=_asn1_find_left(p);
476 if(p3) _asn1_set_right(p3,p2);
477 else{
478 p3=_asn1_find_up(p);
479 if(p3) _asn1_set_down(p3,p2);
480 else {
481 p2->left=NULL;
485 if(p->type & CONST_SIZE) p2->type|=CONST_SIZE;
486 if(p->type & CONST_TAG) p2->type|=CONST_TAG;
487 if(p->type & CONST_OPTION) p2->type|=CONST_OPTION;
488 if(p->type & CONST_DEFAULT) p2->type|=CONST_DEFAULT;
489 if(p->type & CONST_SET) p2->type|=CONST_SET;
490 if(p->type & CONST_NOT_USED) p2->type|=CONST_NOT_USED;
492 if(p==*node) *node=p2;
493 _asn1_remove_node(p);
494 p=p2;
495 move=DOWN;
496 continue;
498 move=DOWN;
500 else move=RIGHT;
502 if(move==DOWN){
503 if(p->down) p=p->down;
504 else move=RIGHT;
507 if(p==*node) {move=UP; continue;}
509 if(move==RIGHT){
510 if(p->right) p=p->right;
511 else move=UP;
513 if(move==UP) p=_asn1_find_up(p);
516 return ASN1_SUCCESS;
521 * asn1_create_element - Creates a structure of type SOURCE_NAME.
522 * @definitions: pointer to the structure returned by "parser_asn1" function
523 * @source_name: the name of the type of the new structure (must be inside p_structure).
524 * @element: pointer to the structure created.
525 * Description:
527 * Creates a structure called DEST_NAME of type SOURCE_NAME.
529 * Returns:
531 * ASN1_SUCCESS\: creation OK
533 * ASN1_ELEMENT_NOT_FOUND\: SOURCE_NAME isn't known
535 * Example: using "pkix.asn"
536 * result=asn1_create_structure(cert_def,"PKIX1.Certificate",&cert);
538 asn1_retCode
539 asn1_create_element(ASN1_TYPE definitions,const char *source_name,
540 ASN1_TYPE *element)
542 node_asn *dest_node;
543 int res;
545 dest_node=_asn1_copy_structure2(definitions,source_name);
547 if(dest_node==NULL) return ASN1_ELEMENT_NOT_FOUND;
549 _asn1_set_name(dest_node,"");
551 res=_asn1_expand_identifier(&dest_node,definitions);
552 _asn1_type_choice_config(dest_node);
554 *element=dest_node;
556 return res;
561 * asn1_print_structure - Prints on the standard output the structure's tree
562 * @out: pointer to the output file (e.g. stdout).
563 * @structure: pointer to the structure that you want to visit.
564 * @name: an element of the structure
566 * Prints on the standard output the structure's tree starting from the NAME element inside
567 * the structure *POINTER.
569 void
570 asn1_print_structure(FILE *out,ASN1_TYPE structure,const char *name,int mode)
572 node_asn *p,*root;
573 int k,indent=0,len,len2,len3;
575 if(out==NULL) return;
577 root=_asn1_find_node(structure,name);
579 if(root==NULL) return;
581 p=root;
582 while(p){
583 if(mode == ASN1_PRINT_ALL){
584 for(k=0;k<indent;k++)fprintf(out," ");
585 fprintf(out,"name:");
586 if(p->name) fprintf(out,"%s ",p->name);
587 else fprintf(out,"NULL ");
589 else{
590 switch(type_field(p->type)){
591 case TYPE_CONSTANT:
592 case TYPE_TAG:
593 case TYPE_SIZE:
594 break;
595 default:
596 for(k=0;k<indent;k++)fprintf(out," ");
597 fprintf(out,"name:");
598 if(p->name) fprintf(out,"%s ",p->name);
599 else fprintf(out,"NULL ");
603 if(mode != ASN1_PRINT_NAME){
604 switch(type_field(p->type)){
605 case TYPE_CONSTANT:
606 if(mode == ASN1_PRINT_ALL)
607 fprintf(out,"type:CONST");break;
608 case TYPE_TAG:
609 if(mode == ASN1_PRINT_ALL)
610 fprintf(out,"type:TAG");break;
611 case TYPE_SIZE:
612 if(mode == ASN1_PRINT_ALL)
613 fprintf(out,"type:SIZE");break;
614 case TYPE_DEFAULT:
615 fprintf(out,"type:DEFAULT");break;
616 case TYPE_NULL:
617 fprintf(out,"type:NULL");break;
618 case TYPE_IDENTIFIER:
619 fprintf(out,"type:IDENTIFIER");break;
620 case TYPE_INTEGER:
621 fprintf(out,"type:INTEGER");break;
622 case TYPE_ENUMERATED:
623 fprintf(out,"type:ENUMERATED");break;
624 case TYPE_TIME:
625 fprintf(out,"type:TIME");break;
626 case TYPE_BOOLEAN:
627 fprintf(out,"type:BOOLEAN");break;
628 case TYPE_SEQUENCE:
629 fprintf(out,"type:SEQUENCE");break;
630 case TYPE_BIT_STRING:
631 fprintf(out,"type:BIT_STR");break;
632 case TYPE_OCTET_STRING:
633 fprintf(out,"type:OCT_STR");break;
634 case TYPE_GENERALSTRING:
635 fprintf(out,"type:GENERALSTRING");break;
636 case TYPE_SEQUENCE_OF:
637 fprintf(out,"type:SEQ_OF");break;
638 case TYPE_OBJECT_ID:
639 fprintf(out,"type:OBJ_ID");break;
640 case TYPE_ANY:
641 fprintf(out,"type:ANY");break;
642 case TYPE_SET:
643 fprintf(out,"type:SET");break;
644 case TYPE_SET_OF:
645 fprintf(out,"type:SET_OF");break;
646 case TYPE_CHOICE:
647 fprintf(out,"type:CHOICE");break;
648 case TYPE_DEFINITIONS:
649 fprintf(out,"type:DEFINITIONS");break;
650 default:
651 break;
655 if((mode == ASN1_PRINT_NAME_TYPE_VALUE) ||
656 (mode == ASN1_PRINT_ALL)){
657 switch(type_field(p->type)){
658 case TYPE_CONSTANT:
659 if(mode == ASN1_PRINT_ALL)
660 if(p->value) fprintf(out," value:%s",p->value);
661 break;
662 case TYPE_TAG:
663 if(mode == ASN1_PRINT_ALL)
664 fprintf(out," value:%s",p->value);
665 break;
666 case TYPE_SIZE:
667 if(mode == ASN1_PRINT_ALL)
668 if(p->value) fprintf(out," value:%s",p->value);
669 break;
670 case TYPE_DEFAULT:
671 if(p->value) fprintf(out," value:%s",p->value);
672 else if(p->type & CONST_TRUE) fprintf(out," value:TRUE");
673 else if(p->type & CONST_FALSE) fprintf(out," value:FALSE");
674 break;
675 case TYPE_IDENTIFIER:
676 if(p->value) fprintf(out," value:%s",p->value);
677 break;
678 case TYPE_INTEGER:
679 if(p->value){
680 len2=-1;
681 len=_asn1_get_length_der(p->value,&len2);
682 fprintf(out," value:0x");
683 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
685 break;
686 case TYPE_ENUMERATED:
687 if(p->value){
688 len2=-1;
689 len=_asn1_get_length_der(p->value,&len2);
690 fprintf(out," value:0x");
691 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
693 break;
694 case TYPE_TIME:
695 if(p->value) fprintf(out," value:%s",p->value);
696 break;
697 case TYPE_BOOLEAN:
698 if(p->value){
699 if(p->value[0]=='T') fprintf(out," value:TRUE");
700 else if(p->value[0]=='F') fprintf(out," value:FALSE");
702 break;
703 case TYPE_BIT_STRING:
704 if(p->value){
705 len2=-1;
706 len=_asn1_get_length_der(p->value,&len2);
707 fprintf(out," value(%i):",(len-1)*8-(p->value[len2]));
708 for(k=1;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
710 break;
711 case TYPE_OCTET_STRING:
712 if(p->value){
713 len2=-1;
714 len=_asn1_get_length_der(p->value,&len2);
715 fprintf(out," value:");
716 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
718 break;
719 case TYPE_GENERALSTRING:
720 if(p->value){
721 len2=-1;
722 len=_asn1_get_length_der(p->value,&len2);
723 fprintf(out," value:");
724 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
726 break;
727 case TYPE_OBJECT_ID:
728 if(p->value) fprintf(out," value:%s",p->value);
729 break;
730 case TYPE_ANY:
731 if(p->value){
732 len3=-1;
733 len2=_asn1_get_length_der(p->value,&len3);
734 fprintf(out," value:");
735 for(k=0;k<len2;k++) fprintf(out,"%02x",(p->value)[k+len3]);
737 break;
738 case TYPE_SET:
739 case TYPE_SET_OF:
740 case TYPE_CHOICE:
741 case TYPE_DEFINITIONS:
742 case TYPE_SEQUENCE_OF:
743 case TYPE_SEQUENCE:
744 case TYPE_NULL:
745 break;
746 default:
747 break;
751 if(mode==ASN1_PRINT_ALL){
752 if(p->type&0x1FFFFF00){
753 fprintf(out," attr:");
754 if(p->type & CONST_UNIVERSAL) fprintf(out,"UNIVERSAL,");
755 if(p->type & CONST_PRIVATE) fprintf(out,"PRIVATE,");
756 if(p->type & CONST_APPLICATION) fprintf(out,"APPLICATION,");
757 if(p->type & CONST_EXPLICIT) fprintf(out,"EXPLICIT,");
758 if(p->type & CONST_IMPLICIT) fprintf(out,"IMPLICIT,");
759 if(p->type & CONST_TAG) fprintf(out,"TAG,");
760 if(p->type & CONST_DEFAULT) fprintf(out,"DEFAULT,");
761 if(p->type & CONST_TRUE) fprintf(out,"TRUE,");
762 if(p->type & CONST_FALSE) fprintf(out,"FALSE,");
763 if(p->type & CONST_LIST) fprintf(out,"LIST,");
764 if(p->type & CONST_MIN_MAX) fprintf(out,"MIN_MAX,");
765 if(p->type & CONST_OPTION) fprintf(out,"OPTION,");
766 if(p->type & CONST_1_PARAM) fprintf(out,"1_PARAM,");
767 if(p->type & CONST_SIZE) fprintf(out,"SIZE,");
768 if(p->type & CONST_DEFINED_BY) fprintf(out,"DEF_BY,");
769 if(p->type & CONST_GENERALIZED) fprintf(out,"GENERALIZED,");
770 if(p->type & CONST_UTC) fprintf(out,"UTC,");
771 if(p->type & CONST_SET) fprintf(out,"SET,");
772 if(p->type & CONST_NOT_USED) fprintf(out,"NOT_USED,");
773 if(p->type & CONST_ASSIGN) fprintf(out,"ASSIGNMENT,");
777 if(mode == ASN1_PRINT_ALL){
778 fprintf(out,"\n");
780 else{
781 switch(type_field(p->type)){
782 case TYPE_CONSTANT:
783 case TYPE_TAG:
784 case TYPE_SIZE:
785 break;
786 default:
787 fprintf(out,"\n");
791 if(p->down){
792 p=p->down;
793 indent+=2;
795 else if(p==root){
796 p=NULL;
797 break;
799 else if(p->right) p=p->right;
800 else{
801 while(1){
802 p=_asn1_find_up(p);
803 if(p==root){
804 p=NULL;
805 break;
807 indent-=2;
808 if(p->right){
809 p=p->right;
810 break;
820 * asn1_number_of_elements - Counts the number of elements of a structure.
821 * @element: pointer to the root of an ASN1 structure.
822 * @name: the name of a sub-structure of ROOT.
823 * @num: pointer to an integer where the result will be stored
824 * Description:
826 * Counts the number of elements of a sub-structure called NAME with names equal to "?1","?2", ...
828 * Returns:
830 * ASN1_SUCCESS\: creation OK
831 * ASN1_ELEMENT_NOT_FOUND\: NAME isn't known
832 * ASN1_GENERIC_ERROR\: pointer num equal to NULL
835 asn1_retCode
836 asn1_number_of_elements(ASN1_TYPE element,const char *name,int *num)
838 node_asn *node,*p;
840 if(num==NULL) return ASN1_GENERIC_ERROR;
842 *num=0;
844 node=_asn1_find_node(element,name);
845 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
847 p=node->down;
849 while(p){
850 if((p->name) && (p->name[0]=='?')) (*num)++;
851 p=p->right;
854 return ASN1_SUCCESS;
859 * asn1_find_structure_from_oid - Search the structure that is defined just
860 * after an OID definition.
861 * @definitions: ASN1 definitions
862 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
863 * Description:
865 * Search the structure that is defined just after an OID definition.
867 * Returns:
869 * NULL when OIDVALUE not found,
871 * otherwise the pointer to a constant string that contains the element
872 * name defined just after the OID.
875 const char*
876 asn1_find_structure_from_oid(ASN1_TYPE definitions,
877 const char *oidValue)
879 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1];
880 char value[MAX_NAME_SIZE];
881 ASN1_TYPE p;
882 int len;
883 asn1_retCode result;
885 if((definitions==ASN1_TYPE_EMPTY) || (oidValue==NULL))
886 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
889 strcpy(definitionsName,definitions->name);
890 strcat(definitionsName,".");
892 /* search the OBJECT_ID into definitions */
893 p=definitions->down;
894 while(p){
895 if((type_field(p->type)==TYPE_OBJECT_ID) &&
896 (p->type & CONST_ASSIGN)){
897 strcpy(name,definitionsName);
898 strcat(name,p->name);
900 len=MAX_NAME_SIZE;
901 result=asn1_read_value(definitions,name,value,&len);
903 if((result == ASN1_SUCCESS) && (!strcmp(oidValue,value))){
904 p=p->right;
905 if(p==NULL) /* reach the end of ASN1 definitions */
906 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
908 return p->name;
911 p=p->right;
914 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */