Revert, don't export asn1_find_up.
[libtasn1.git] / lib / structure.c
blob3eaf338ad39e9495c070f3a4d90de23d41a0df63
1 /*
2 * Copyright (C) 2004, 2006 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
24 /*****************************************************/
25 /* File: structure.c */
26 /* Description: Functions to create and delete an */
27 /* ASN1 tree. */
28 /*****************************************************/
31 #include <int.h>
32 #include <errors.h>
33 #include <structure.h>
34 #include "parser_aux.h"
35 #include <gstr.h>
38 extern char _asn1_identifierMissing[];
41 /******************************************************/
42 /* Function : _asn1_add_node_only */
43 /* Description: creates a new NODE_ASN element. */
44 /* Parameters: */
45 /* type: type of the new element (see TYPE_ */
46 /* and CONST_ constants). */
47 /* Return: pointer to the new element. */
48 /******************************************************/
49 node_asn *
50 _asn1_add_node_only(unsigned int type)
52 node_asn *punt;
54 punt=(node_asn *) _asn1_malloc(sizeof(node_asn));
55 if (punt==NULL) return NULL;
57 punt->left=NULL;
58 punt->name=NULL;
59 punt->type=type;
60 punt->value=NULL;
61 punt->down=NULL;
62 punt->right=NULL;
64 return punt;
68 /******************************************************************/
69 /* Function : _asn1_find_left */
70 /* Description: returns the NODE_ASN element with RIGHT field that*/
71 /* points the element NODE. */
72 /* Parameters: */
73 /* node: NODE_ASN element pointer. */
74 /* Return: NULL if not found. */
75 /******************************************************************/
76 node_asn *
77 _asn1_find_left(node_asn *node)
79 if((node==NULL) || (node->left==NULL) ||
80 (node->left->down==node)) return NULL;
82 return node->left;
86 asn1_retCode
87 _asn1_create_static_structure(ASN1_TYPE pointer,char* output_file_name,char *vector_name)
89 FILE *file;
90 node_asn *p;
91 unsigned long t;
93 file=fopen( output_file_name,"w");
95 if(file==NULL) return ASN1_FILE_NOT_FOUND;
97 fprintf(file,"\n#include \"libtasn1.h\"\n\n");
98 fprintf(file,"const ASN1_ARRAY_TYPE %s[]={\n",vector_name);
100 p=pointer;
102 while(p){
103 fprintf(file," {");
105 if(p->name) fprintf(file,"\"%s\",",p->name);
106 else fprintf(file,"0,");
108 t=p->type;
109 if(p->down) t|=CONST_DOWN;
110 if(p->right) t|=CONST_RIGHT;
112 fprintf(file,"%lu,",t);
114 if(p->value) fprintf(file,"\"%s\"},\n",p->value);
115 else fprintf(file,"0},\n");
117 if(p->down){
118 p=p->down;
120 else if(p->right){
121 p=p->right;
123 else{
124 while(1){
125 p=_asn1_find_up(p);
126 if(p==pointer){
127 p=NULL;
128 break;
130 if(p->right){
131 p=p->right;
132 break;
138 fprintf(file," {0,0,0}\n};\n");
140 fclose(file);
142 return ASN1_SUCCESS;
147 * asn1_array2tree - Creates the structures needed to manage the ASN1 definitions.
148 * @array: specify the array that contains ASN.1 declarations
149 * @definitions: return the pointer to the structure created by
150 * *ARRAY ASN.1 declarations
151 * @errorDescription: return the error description.
153 * Creates the structures needed to manage the ASN.1 definitions.
154 * @array is a vector created by asn1_parser2array().
156 * Returns:
158 * ASN1_SUCCESS: Structure created correctly.
160 * ASN1_ELEMENT_NOT_EMPTY: *@definitions not ASN1_TYPE_EMPTY.
162 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
163 * is not defined (see @errorDescription for more information).
165 * ASN1_ARRAY_ERROR: The array pointed by @array is wrong.
167 asn1_retCode
168 asn1_array2tree(const ASN1_ARRAY_TYPE *array,ASN1_TYPE *definitions,
169 char *errorDescription)
171 node_asn *p,*p_last=NULL;
172 unsigned long k;
173 int move;
174 asn1_retCode result;
177 if(*definitions != ASN1_TYPE_EMPTY)
178 return ASN1_ELEMENT_NOT_EMPTY;
180 move=UP;
182 k=0;
183 while(array[k].value || array[k].type || array[k].name){
184 p=_asn1_add_node(array[k].type&(~CONST_DOWN));
185 if(array[k].name) _asn1_set_name(p,array[k].name);
186 if(array[k].value) _asn1_set_value(p,array[k].value,
187 strlen(array[k].value)+1);
189 if(*definitions==NULL) *definitions=p;
191 if(move==DOWN) _asn1_set_down(p_last,p);
192 else if(move==RIGHT) _asn1_set_right(p_last,p);
194 p_last=p;
196 if(array[k].type&CONST_DOWN) move=DOWN;
197 else if(array[k].type&CONST_RIGHT) move=RIGHT;
198 else{
199 while(1){
200 if(p_last==*definitions) break;
202 p_last= _asn1_find_up(p_last);
204 if(p_last==NULL) break;
206 if(p_last->type&CONST_RIGHT){
207 p_last->type&=~CONST_RIGHT;
208 move=RIGHT;
209 break;
211 } /* while */
213 k++;
214 } /* while */
216 if(p_last==*definitions){
217 result=_asn1_check_identifier(*definitions);
218 if(result==ASN1_SUCCESS){
219 _asn1_change_integer_value(*definitions);
220 _asn1_expand_object_id(*definitions);
223 else{
224 result=ASN1_ARRAY_ERROR;
227 if (errorDescription!=NULL) {
228 if(result==ASN1_IDENTIFIER_NOT_FOUND) {
229 Estrcpy(errorDescription,":: identifier '");
230 Estrcat(errorDescription,_asn1_identifierMissing);
231 Estrcat(errorDescription,"' not found");
233 else
234 errorDescription[0]=0;
237 if(result != ASN1_SUCCESS){
238 _asn1_delete_list_and_nodes();
239 *definitions=ASN1_TYPE_EMPTY;
241 else
242 _asn1_delete_list();
244 return result;
249 * asn1_delete_structure - Deletes the structure pointed by *ROOT.
250 * @structure: pointer to the structure that you want to delete.
252 * Deletes the structure *@structure. At the end, *@structure is set
253 * to ASN1_TYPE_EMPTY.
255 * Returns:
257 * ASN1_SUCCESS: Everything OK.
259 * ASN1_ELEMENT_NOT_FOUND: *@structure was ASN1_TYPE_EMPTY.
262 asn1_retCode
263 asn1_delete_structure(ASN1_TYPE *structure)
265 node_asn *p,*p2,*p3;
267 if(*structure==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
269 p=*structure;
270 while(p){
271 if(p->down){
272 p=p->down;
274 else{ /* no down */
275 p2=p->right;
276 if(p!=*structure){
277 p3=_asn1_find_up(p);
278 _asn1_set_down(p3,p2);
279 _asn1_remove_node(p);
280 p=p3;
282 else{ /* p==root */
283 p3=_asn1_find_left(p);
284 if(!p3){
285 p3=_asn1_find_up(p);
286 if(p3) _asn1_set_down(p3,p2);
287 else{
288 if(p->right) p->right->left=NULL;
291 else _asn1_set_right(p3,p2);
292 _asn1_remove_node(p);
293 p=NULL;
298 *structure=ASN1_TYPE_EMPTY;
299 return ASN1_SUCCESS;
304 * asn1_delete_element - Deletes the element of a structure.
305 * @structure: pointer to the structure that contains the element you
306 * want to delete.
307 * @element_name: element's name you want to delete.
309 * Deletes the element named *@element_name inside *@structure.
311 * Returns:
313 * ASN1_SUCCESS: Everything OK.
315 * ASN1_ELEMENT_NOT_FOUND: The name element was not found.
318 asn1_retCode
319 asn1_delete_element(ASN1_TYPE structure,const char *element_name)
321 node_asn *p2,*p3,*source_node;
323 source_node=asn1_find_node(structure,element_name);
325 if(source_node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
327 p2=source_node->right;
328 p3=_asn1_find_left(source_node);
329 if(!p3){
330 p3=_asn1_find_up(source_node);
331 if(p3)
332 _asn1_set_down(p3,p2);
333 else
334 if(source_node->right) source_node->right->left=NULL;
336 else _asn1_set_right(p3,p2);
338 return asn1_delete_structure(&source_node);
342 node_asn *
343 _asn1_copy_structure3(node_asn *source_node)
345 node_asn *dest_node,*p_s,*p_d,*p_d_prev;
346 int len,len2,move, tlen;
348 if(source_node==NULL) return NULL;
350 dest_node=_asn1_add_node_only(source_node->type);
352 p_s=source_node;
353 p_d=dest_node;
355 move=DOWN;
358 if(move!=UP){
359 if(p_s->name) _asn1_set_name(p_d,p_s->name);
360 if(p_s->value){
361 switch(type_field(p_s->type)){
362 case TYPE_OCTET_STRING: case TYPE_BIT_STRING: case TYPE_GENERALSTRING:
363 case TYPE_INTEGER:
364 len2=-1;
365 len=asn1_get_length_der(p_s->value,p_s->value_len,&len2);
366 if (len < 0) return NULL;
367 _asn1_set_value(p_d,p_s->value,len+len2);
368 break;
369 default:
370 tlen = strlen(p_s->value);
372 if (tlen > 0)
373 _asn1_set_value(p_d,p_s->value,tlen+1);
376 move=DOWN;
378 else move=RIGHT;
380 if(move==DOWN){
381 if(p_s->down){
382 p_s=p_s->down;
383 p_d_prev=p_d;
384 p_d=_asn1_add_node_only(p_s->type);
385 _asn1_set_down(p_d_prev,p_d);
387 else move=RIGHT;
390 if(p_s==source_node) break;
392 if(move==RIGHT){
393 if(p_s->right){
394 p_s=p_s->right;
395 p_d_prev=p_d;
396 p_d=_asn1_add_node_only(p_s->type);
397 _asn1_set_right(p_d_prev,p_d);
399 else move=UP;
401 if(move==UP){
402 p_s=_asn1_find_up(p_s);
403 p_d=_asn1_find_up(p_d);
405 }while(p_s!=source_node);
407 return dest_node;
411 node_asn *
412 _asn1_copy_structure2(node_asn *root,const char *source_name)
414 node_asn *source_node;
416 source_node=asn1_find_node(root,source_name);
418 return _asn1_copy_structure3(source_node);
423 asn1_retCode
424 _asn1_type_choice_config(node_asn *node)
426 node_asn *p,*p2,*p3,*p4;
427 int move,tlen;
429 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
431 p=node;
432 move=DOWN;
434 while(!((p==node) && (move==UP))){
435 if(move!=UP){
436 if((type_field(p->type)==TYPE_CHOICE) &&
437 (p->type&CONST_TAG)){
438 p2=p->down;
439 while(p2){
440 if(type_field(p2->type)!=TYPE_TAG){
441 p2->type|=CONST_TAG;
442 p3=_asn1_find_left(p2);
443 while(p3){
444 if(type_field(p3->type)==TYPE_TAG){
445 p4=_asn1_add_node_only(p3->type);
446 tlen = strlen(p3->value);
447 if (tlen > 0)
448 _asn1_set_value(p4,p3->value,tlen+1);
449 _asn1_set_right(p4,p2->down);
450 _asn1_set_down(p2,p4);
452 p3=_asn1_find_left(p3);
455 p2=p2->right;
457 p->type&=~(CONST_TAG);
458 p2=p->down;
459 while(p2){
460 p3=p2->right;
461 if(type_field(p2->type)==TYPE_TAG) asn1_delete_structure(&p2);
462 p2=p3;
465 move=DOWN;
467 else move=RIGHT;
469 if(move==DOWN){
470 if(p->down) p=p->down;
471 else move=RIGHT;
474 if(p==node) {move=UP; continue;}
476 if(move==RIGHT){
477 if(p->right) p=p->right;
478 else move=UP;
480 if(move==UP) p=_asn1_find_up(p);
483 return ASN1_SUCCESS;
487 asn1_retCode
488 _asn1_expand_identifier(node_asn **node,node_asn *root)
490 node_asn *p,*p2,*p3;
491 char name2[MAX_NAME_SIZE+2];
492 int move;
494 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
496 p=*node;
497 move=DOWN;
499 while(!((p==*node) && (move==UP))){
500 if(move!=UP){
501 if(type_field(p->type)==TYPE_IDENTIFIER){
502 _asn1_str_cpy(name2, sizeof(name2), root->name);
503 _asn1_str_cat(name2, sizeof(name2), ".");
504 _asn1_str_cat(name2, sizeof(name2), p->value);
505 p2=_asn1_copy_structure2(root,name2);
506 if(p2==NULL){
507 return ASN1_IDENTIFIER_NOT_FOUND;
509 _asn1_set_name(p2,p->name);
510 p2->right=p->right;
511 p2->left=p->left;
512 if(p->right) p->right->left=p2;
513 p3=p->down;
514 if(p3){
515 while(p3->right) p3=p3->right;
516 _asn1_set_right(p3,p2->down);
517 _asn1_set_down(p2,p->down);
520 p3=_asn1_find_left(p);
521 if(p3) _asn1_set_right(p3,p2);
522 else{
523 p3=_asn1_find_up(p);
524 if(p3) _asn1_set_down(p3,p2);
525 else {
526 p2->left=NULL;
530 if(p->type & CONST_SIZE) p2->type|=CONST_SIZE;
531 if(p->type & CONST_TAG) p2->type|=CONST_TAG;
532 if(p->type & CONST_OPTION) p2->type|=CONST_OPTION;
533 if(p->type & CONST_DEFAULT) p2->type|=CONST_DEFAULT;
534 if(p->type & CONST_SET) p2->type|=CONST_SET;
535 if(p->type & CONST_NOT_USED) p2->type|=CONST_NOT_USED;
537 if(p==*node) *node=p2;
538 _asn1_remove_node(p);
539 p=p2;
540 move=DOWN;
541 continue;
543 move=DOWN;
545 else move=RIGHT;
547 if(move==DOWN){
548 if(p->down) p=p->down;
549 else move=RIGHT;
552 if(p==*node) {move=UP; continue;}
554 if(move==RIGHT){
555 if(p->right) p=p->right;
556 else move=UP;
558 if(move==UP) p=_asn1_find_up(p);
561 return ASN1_SUCCESS;
566 * asn1_create_element - Creates a structure of type SOURCE_NAME.
567 * @definitions: pointer to the structure returned by "parser_asn1" function
568 * @source_name: the name of the type of the new structure (must be
569 * inside p_structure).
570 * @element: pointer to the structure created.
572 * Creates a structure of type @source_name. Example using
573 * "pkix.asn":
575 * rc = asn1_create_structure(cert_def, "PKIX1.Certificate",
576 * certptr);
578 * Returns:
580 * ASN1_SUCCESS: Creation OK.
582 * ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
584 asn1_retCode
585 asn1_create_element(ASN1_TYPE definitions,const char *source_name,
586 ASN1_TYPE *element)
588 node_asn *dest_node;
589 int res;
591 dest_node=_asn1_copy_structure2(definitions,source_name);
593 if(dest_node==NULL) return ASN1_ELEMENT_NOT_FOUND;
595 _asn1_set_name(dest_node,"");
597 res=_asn1_expand_identifier(&dest_node,definitions);
598 _asn1_type_choice_config(dest_node);
600 *element=dest_node;
602 return res;
607 * asn1_print_structure - Prints on the standard output the structure's tree
608 * @out: pointer to the output file (e.g. stdout).
609 * @structure: pointer to the structure that you want to visit.
610 * @name: an element of the structure
611 * @mode: specify how much of the structure to print, can be
612 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
613 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
615 * Prints on the @out file descriptor the structure's tree starting
616 * from the @name element inside the structure @structure.
618 void
619 asn1_print_structure(FILE *out,ASN1_TYPE structure,const char *name,int mode)
621 node_asn *p,*root;
622 int k,indent=0,len,len2,len3;
624 if(out==NULL) return;
626 root=asn1_find_node(structure,name);
628 if(root==NULL) return;
630 p=root;
631 while(p){
632 if(mode == ASN1_PRINT_ALL){
633 for(k=0;k<indent;k++)fprintf(out," ");
634 fprintf(out,"name:");
635 if(p->name) fprintf(out,"%s ",p->name);
636 else fprintf(out,"NULL ");
638 else{
639 switch(type_field(p->type)){
640 case TYPE_CONSTANT:
641 case TYPE_TAG:
642 case TYPE_SIZE:
643 break;
644 default:
645 for(k=0;k<indent;k++)fprintf(out," ");
646 fprintf(out,"name:");
647 if(p->name) fprintf(out,"%s ",p->name);
648 else fprintf(out,"NULL ");
652 if(mode != ASN1_PRINT_NAME){
653 switch(type_field(p->type)){
654 case TYPE_CONSTANT:
655 if(mode == ASN1_PRINT_ALL)
656 fprintf(out,"type:CONST");break;
657 case TYPE_TAG:
658 if(mode == ASN1_PRINT_ALL)
659 fprintf(out,"type:TAG");break;
660 case TYPE_SIZE:
661 if(mode == ASN1_PRINT_ALL)
662 fprintf(out,"type:SIZE");break;
663 case TYPE_DEFAULT:
664 fprintf(out,"type:DEFAULT");break;
665 case TYPE_NULL:
666 fprintf(out,"type:NULL");break;
667 case TYPE_IDENTIFIER:
668 fprintf(out,"type:IDENTIFIER");break;
669 case TYPE_INTEGER:
670 fprintf(out,"type:INTEGER");break;
671 case TYPE_ENUMERATED:
672 fprintf(out,"type:ENUMERATED");break;
673 case TYPE_TIME:
674 fprintf(out,"type:TIME");break;
675 case TYPE_BOOLEAN:
676 fprintf(out,"type:BOOLEAN");break;
677 case TYPE_SEQUENCE:
678 fprintf(out,"type:SEQUENCE");break;
679 case TYPE_BIT_STRING:
680 fprintf(out,"type:BIT_STR");break;
681 case TYPE_OCTET_STRING:
682 fprintf(out,"type:OCT_STR");break;
683 case TYPE_GENERALSTRING:
684 fprintf(out,"type:GENERALSTRING");break;
685 case TYPE_SEQUENCE_OF:
686 fprintf(out,"type:SEQ_OF");break;
687 case TYPE_OBJECT_ID:
688 fprintf(out,"type:OBJ_ID");break;
689 case TYPE_ANY:
690 fprintf(out,"type:ANY");break;
691 case TYPE_SET:
692 fprintf(out,"type:SET");break;
693 case TYPE_SET_OF:
694 fprintf(out,"type:SET_OF");break;
695 case TYPE_CHOICE:
696 fprintf(out,"type:CHOICE");break;
697 case TYPE_DEFINITIONS:
698 fprintf(out,"type:DEFINITIONS");break;
699 default:
700 break;
704 if((mode == ASN1_PRINT_NAME_TYPE_VALUE) ||
705 (mode == ASN1_PRINT_ALL)){
706 switch(type_field(p->type)){
707 case TYPE_CONSTANT:
708 if(mode == ASN1_PRINT_ALL)
709 if(p->value) fprintf(out," value:%s",p->value);
710 break;
711 case TYPE_TAG:
712 if(mode == ASN1_PRINT_ALL)
713 if (p->value) fprintf(out," value:%s",p->value);
714 break;
715 case TYPE_SIZE:
716 if(mode == ASN1_PRINT_ALL)
717 if(p->value) fprintf(out," value:%s",p->value);
718 break;
719 case TYPE_DEFAULT:
720 if(p->value) fprintf(out," value:%s",p->value);
721 else if(p->type & CONST_TRUE) fprintf(out," value:TRUE");
722 else if(p->type & CONST_FALSE) fprintf(out," value:FALSE");
723 break;
724 case TYPE_IDENTIFIER:
725 if(p->value) fprintf(out," value:%s",p->value);
726 break;
727 case TYPE_INTEGER:
728 if(p->value){
729 len2=-1;
730 len=asn1_get_length_der(p->value,p->value_len,&len2);
731 fprintf(out," value:0x");
732 if (len > 0)
733 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
735 break;
736 case TYPE_ENUMERATED:
737 if(p->value){
738 len2=-1;
739 len=asn1_get_length_der(p->value,p->value_len,&len2);
740 fprintf(out," value:0x");
741 if (len > 0)
742 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
744 break;
745 case TYPE_TIME:
746 if(p->value) fprintf(out," value:%s",p->value);
747 break;
748 case TYPE_BOOLEAN:
749 if(p->value){
750 if(p->value[0]=='T') fprintf(out," value:TRUE");
751 else if(p->value[0]=='F') fprintf(out," value:FALSE");
753 break;
754 case TYPE_BIT_STRING:
755 if(p->value){
756 len2=-1;
757 len=asn1_get_length_der(p->value,p->value_len,&len2);
758 if (len>0)
760 fprintf(out," value(%i):",(len-1)*8-(p->value[len2]));
761 for(k=1;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
764 break;
765 case TYPE_OCTET_STRING:
766 if(p->value){
767 len2=-1;
768 len=asn1_get_length_der(p->value,p->value_len,&len2);
769 fprintf(out," value:");
770 if (len>0)
771 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
773 break;
774 case TYPE_GENERALSTRING:
775 if(p->value){
776 len2=-1;
777 len=asn1_get_length_der(p->value,p->value_len,&len2);
778 fprintf(out," value:");
779 if (len>0)
780 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
782 break;
783 case TYPE_OBJECT_ID:
784 if(p->value) fprintf(out," value:%s",p->value);
785 break;
786 case TYPE_ANY:
787 if(p->value){
788 len3=-1;
789 len2=asn1_get_length_der(p->value,p->value_len,&len3);
790 fprintf(out," value:");
791 if (len2>0)
792 for(k=0;k<len2;k++) fprintf(out,"%02x",(p->value)[k+len3]);
794 break;
795 case TYPE_SET:
796 case TYPE_SET_OF:
797 case TYPE_CHOICE:
798 case TYPE_DEFINITIONS:
799 case TYPE_SEQUENCE_OF:
800 case TYPE_SEQUENCE:
801 case TYPE_NULL:
802 break;
803 default:
804 break;
808 if(mode==ASN1_PRINT_ALL){
809 if(p->type&0x1FFFFF00){
810 fprintf(out," attr:");
811 if(p->type & CONST_UNIVERSAL) fprintf(out,"UNIVERSAL,");
812 if(p->type & CONST_PRIVATE) fprintf(out,"PRIVATE,");
813 if(p->type & CONST_APPLICATION) fprintf(out,"APPLICATION,");
814 if(p->type & CONST_EXPLICIT) fprintf(out,"EXPLICIT,");
815 if(p->type & CONST_IMPLICIT) fprintf(out,"IMPLICIT,");
816 if(p->type & CONST_TAG) fprintf(out,"TAG,");
817 if(p->type & CONST_DEFAULT) fprintf(out,"DEFAULT,");
818 if(p->type & CONST_TRUE) fprintf(out,"TRUE,");
819 if(p->type & CONST_FALSE) fprintf(out,"FALSE,");
820 if(p->type & CONST_LIST) fprintf(out,"LIST,");
821 if(p->type & CONST_MIN_MAX) fprintf(out,"MIN_MAX,");
822 if(p->type & CONST_OPTION) fprintf(out,"OPTION,");
823 if(p->type & CONST_1_PARAM) fprintf(out,"1_PARAM,");
824 if(p->type & CONST_SIZE) fprintf(out,"SIZE,");
825 if(p->type & CONST_DEFINED_BY) fprintf(out,"DEF_BY,");
826 if(p->type & CONST_GENERALIZED) fprintf(out,"GENERALIZED,");
827 if(p->type & CONST_UTC) fprintf(out,"UTC,");
828 if(p->type & CONST_SET) fprintf(out,"SET,");
829 if(p->type & CONST_NOT_USED) fprintf(out,"NOT_USED,");
830 if(p->type & CONST_ASSIGN) fprintf(out,"ASSIGNMENT,");
834 if(mode == ASN1_PRINT_ALL){
835 fprintf(out,"\n");
837 else{
838 switch(type_field(p->type)){
839 case TYPE_CONSTANT:
840 case TYPE_TAG:
841 case TYPE_SIZE:
842 break;
843 default:
844 fprintf(out,"\n");
848 if(p->down){
849 p=p->down;
850 indent+=2;
852 else if(p==root){
853 p=NULL;
854 break;
856 else if(p->right) p=p->right;
857 else{
858 while(1){
859 p=_asn1_find_up(p);
860 if(p==root){
861 p=NULL;
862 break;
864 indent-=2;
865 if(p->right){
866 p=p->right;
867 break;
877 * asn1_number_of_elements - Counts the number of elements of a structure.
878 * @element: pointer to the root of an ASN1 structure.
879 * @name: the name of a sub-structure of ROOT.
880 * @num: pointer to an integer where the result will be stored
882 * Counts the number of elements of a sub-structure called NAME with
883 * names equal to "?1","?2", ...
885 * Returns:
887 * ASN1_SUCCESS: Creation OK.
889 * ASN1_ELEMENT_NOT_FOUND: NAME isn't known.
891 * ASN1_GENERIC_ERROR: Pointer num equal to NULL.
894 asn1_retCode
895 asn1_number_of_elements(ASN1_TYPE element,const char *name,int *num)
897 node_asn *node,*p;
899 if(num==NULL) return ASN1_GENERIC_ERROR;
901 *num=0;
903 node=asn1_find_node(element,name);
904 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
906 p=node->down;
908 while(p){
909 if((p->name) && (p->name[0]=='?')) (*num)++;
910 p=p->right;
913 return ASN1_SUCCESS;
918 * asn1_find_structure_from_oid - Locate structure defined by a specific OID.
919 * @definitions: ASN1 definitions
920 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
922 * Search the structure that is defined just after an OID definition.
924 * Returns: NULL when OIDVALUE not found, otherwise the pointer to a
925 * constant string that contains the element name defined just
926 * after the OID.
929 const char*
930 asn1_find_structure_from_oid (ASN1_TYPE definitions,
931 const char *oidValue)
933 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1];
934 char value[MAX_NAME_SIZE];
935 ASN1_TYPE p;
936 int len;
937 asn1_retCode result;
939 if((definitions==ASN1_TYPE_EMPTY) || (oidValue==NULL))
940 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
943 strcpy(definitionsName,definitions->name);
944 strcat(definitionsName,".");
946 /* search the OBJECT_ID into definitions */
947 p=definitions->down;
948 while(p){
949 if((type_field(p->type)==TYPE_OBJECT_ID) &&
950 (p->type & CONST_ASSIGN)){
951 strcpy(name,definitionsName);
952 strcat(name,p->name);
954 len=MAX_NAME_SIZE;
955 result=asn1_read_value(definitions,name,value,&len);
957 if((result == ASN1_SUCCESS) && (!strcmp(oidValue,value))){
958 p=p->right;
959 if(p==NULL) /* reach the end of ASN1 definitions */
960 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
962 return p->name;
965 p=p->right;
968 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */