Update.
[libtasn1.git] / lib / structure.c
blob9909c7dd1ae4daa749dd9e3651be15b085c93784
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);
341 node_asn *
342 _asn1_copy_structure3(node_asn *source_node)
344 node_asn *dest_node,*p_s,*p_d,*p_d_prev;
345 int len,len2,move, tlen;
347 if(source_node==NULL) return NULL;
349 dest_node=_asn1_add_node_only(source_node->type);
351 p_s=source_node;
352 p_d=dest_node;
354 move=DOWN;
357 if(move!=UP){
358 if(p_s->name) _asn1_set_name(p_d,p_s->name);
359 if(p_s->value){
360 switch(type_field(p_s->type)){
361 case TYPE_OCTET_STRING: case TYPE_BIT_STRING: case TYPE_GENERALSTRING:
362 case TYPE_INTEGER:
363 len2=-1;
364 len=asn1_get_length_der(p_s->value,p_s->value_len,&len2);
365 if (len < 0) return NULL;
366 _asn1_set_value(p_d,p_s->value,len+len2);
367 break;
368 default:
369 tlen = strlen(p_s->value);
371 if (tlen > 0)
372 _asn1_set_value(p_d,p_s->value,tlen+1);
375 move=DOWN;
377 else move=RIGHT;
379 if(move==DOWN){
380 if(p_s->down){
381 p_s=p_s->down;
382 p_d_prev=p_d;
383 p_d=_asn1_add_node_only(p_s->type);
384 _asn1_set_down(p_d_prev,p_d);
386 else move=RIGHT;
389 if(p_s==source_node) break;
391 if(move==RIGHT){
392 if(p_s->right){
393 p_s=p_s->right;
394 p_d_prev=p_d;
395 p_d=_asn1_add_node_only(p_s->type);
396 _asn1_set_right(p_d_prev,p_d);
398 else move=UP;
400 if(move==UP){
401 p_s=_asn1_find_up(p_s);
402 p_d=_asn1_find_up(p_d);
404 }while(p_s!=source_node);
406 return dest_node;
410 node_asn *
411 _asn1_copy_structure2(node_asn *root,const char *source_name)
413 node_asn *source_node;
415 source_node=asn1_find_node(root,source_name);
417 return _asn1_copy_structure3(source_node);
422 asn1_retCode
423 _asn1_type_choice_config(node_asn *node)
425 node_asn *p,*p2,*p3,*p4;
426 int move,tlen;
428 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
430 p=node;
431 move=DOWN;
433 while(!((p==node) && (move==UP))){
434 if(move!=UP){
435 if((type_field(p->type)==TYPE_CHOICE) &&
436 (p->type&CONST_TAG)){
437 p2=p->down;
438 while(p2){
439 if(type_field(p2->type)!=TYPE_TAG){
440 p2->type|=CONST_TAG;
441 p3=_asn1_find_left(p2);
442 while(p3){
443 if(type_field(p3->type)==TYPE_TAG){
444 p4=_asn1_add_node_only(p3->type);
445 tlen = strlen(p3->value);
446 if (tlen > 0)
447 _asn1_set_value(p4,p3->value,tlen+1);
448 _asn1_set_right(p4,p2->down);
449 _asn1_set_down(p2,p4);
451 p3=_asn1_find_left(p3);
454 p2=p2->right;
456 p->type&=~(CONST_TAG);
457 p2=p->down;
458 while(p2){
459 p3=p2->right;
460 if(type_field(p2->type)==TYPE_TAG) asn1_delete_structure(&p2);
461 p2=p3;
464 move=DOWN;
466 else move=RIGHT;
468 if(move==DOWN){
469 if(p->down) p=p->down;
470 else move=RIGHT;
473 if(p==node) {move=UP; continue;}
475 if(move==RIGHT){
476 if(p->right) p=p->right;
477 else move=UP;
479 if(move==UP) p=_asn1_find_up(p);
482 return ASN1_SUCCESS;
486 asn1_retCode
487 _asn1_expand_identifier(node_asn **node,node_asn *root)
489 node_asn *p,*p2,*p3;
490 char name2[MAX_NAME_SIZE+2];
491 int move;
493 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
495 p=*node;
496 move=DOWN;
498 while(!((p==*node) && (move==UP))){
499 if(move!=UP){
500 if(type_field(p->type)==TYPE_IDENTIFIER){
501 _asn1_str_cpy(name2, sizeof(name2), root->name);
502 _asn1_str_cat(name2, sizeof(name2), ".");
503 _asn1_str_cat(name2, sizeof(name2), p->value);
504 p2=_asn1_copy_structure2(root,name2);
505 if(p2==NULL){
506 return ASN1_IDENTIFIER_NOT_FOUND;
508 _asn1_set_name(p2,p->name);
509 p2->right=p->right;
510 p2->left=p->left;
511 if(p->right) p->right->left=p2;
512 p3=p->down;
513 if(p3){
514 while(p3->right) p3=p3->right;
515 _asn1_set_right(p3,p2->down);
516 _asn1_set_down(p2,p->down);
519 p3=_asn1_find_left(p);
520 if(p3) _asn1_set_right(p3,p2);
521 else{
522 p3=_asn1_find_up(p);
523 if(p3) _asn1_set_down(p3,p2);
524 else {
525 p2->left=NULL;
529 if(p->type & CONST_SIZE) p2->type|=CONST_SIZE;
530 if(p->type & CONST_TAG) p2->type|=CONST_TAG;
531 if(p->type & CONST_OPTION) p2->type|=CONST_OPTION;
532 if(p->type & CONST_DEFAULT) p2->type|=CONST_DEFAULT;
533 if(p->type & CONST_SET) p2->type|=CONST_SET;
534 if(p->type & CONST_NOT_USED) p2->type|=CONST_NOT_USED;
536 if(p==*node) *node=p2;
537 _asn1_remove_node(p);
538 p=p2;
539 move=DOWN;
540 continue;
542 move=DOWN;
544 else move=RIGHT;
546 if(move==DOWN){
547 if(p->down) p=p->down;
548 else move=RIGHT;
551 if(p==*node) {move=UP; continue;}
553 if(move==RIGHT){
554 if(p->right) p=p->right;
555 else move=UP;
557 if(move==UP) p=_asn1_find_up(p);
560 return ASN1_SUCCESS;
565 * asn1_create_element - Creates a structure of type SOURCE_NAME.
566 * @definitions: pointer to the structure returned by "parser_asn1" function
567 * @source_name: the name of the type of the new structure (must be
568 * inside p_structure).
569 * @element: pointer to the structure created.
571 * Creates a structure of type @source_name. Example using
572 * "pkix.asn":
574 * rc = asn1_create_structure(cert_def, "PKIX1.Certificate",
575 * certptr);
577 * Returns:
579 * ASN1_SUCCESS: Creation OK.
581 * ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
583 asn1_retCode
584 asn1_create_element(ASN1_TYPE definitions,const char *source_name,
585 ASN1_TYPE *element)
587 node_asn *dest_node;
588 int res;
590 dest_node=_asn1_copy_structure2(definitions,source_name);
592 if(dest_node==NULL) return ASN1_ELEMENT_NOT_FOUND;
594 _asn1_set_name(dest_node,"");
596 res=_asn1_expand_identifier(&dest_node,definitions);
597 _asn1_type_choice_config(dest_node);
599 *element=dest_node;
601 return res;
606 * asn1_print_structure - Prints on the standard output the structure's tree
607 * @out: pointer to the output file (e.g. stdout).
608 * @structure: pointer to the structure that you want to visit.
609 * @name: an element of the structure
610 * @mode: specify how much of the structure to print, can be
611 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
612 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
614 * Prints on the @out file descriptor the structure's tree starting
615 * from the @name element inside the structure @structure.
617 void
618 asn1_print_structure(FILE *out,ASN1_TYPE structure,const char *name,int mode)
620 node_asn *p,*root;
621 int k,indent=0,len,len2,len3;
623 if(out==NULL) return;
625 root=asn1_find_node(structure,name);
627 if(root==NULL) return;
629 p=root;
630 while(p){
631 if(mode == ASN1_PRINT_ALL){
632 for(k=0;k<indent;k++)fprintf(out," ");
633 fprintf(out,"name:");
634 if(p->name) fprintf(out,"%s ",p->name);
635 else fprintf(out,"NULL ");
637 else{
638 switch(type_field(p->type)){
639 case TYPE_CONSTANT:
640 case TYPE_TAG:
641 case TYPE_SIZE:
642 break;
643 default:
644 for(k=0;k<indent;k++)fprintf(out," ");
645 fprintf(out,"name:");
646 if(p->name) fprintf(out,"%s ",p->name);
647 else fprintf(out,"NULL ");
651 if(mode != ASN1_PRINT_NAME){
652 switch(type_field(p->type)){
653 case TYPE_CONSTANT:
654 if(mode == ASN1_PRINT_ALL)
655 fprintf(out,"type:CONST");break;
656 case TYPE_TAG:
657 if(mode == ASN1_PRINT_ALL)
658 fprintf(out,"type:TAG");break;
659 case TYPE_SIZE:
660 if(mode == ASN1_PRINT_ALL)
661 fprintf(out,"type:SIZE");break;
662 case TYPE_DEFAULT:
663 fprintf(out,"type:DEFAULT");break;
664 case TYPE_NULL:
665 fprintf(out,"type:NULL");break;
666 case TYPE_IDENTIFIER:
667 fprintf(out,"type:IDENTIFIER");break;
668 case TYPE_INTEGER:
669 fprintf(out,"type:INTEGER");break;
670 case TYPE_ENUMERATED:
671 fprintf(out,"type:ENUMERATED");break;
672 case TYPE_TIME:
673 fprintf(out,"type:TIME");break;
674 case TYPE_BOOLEAN:
675 fprintf(out,"type:BOOLEAN");break;
676 case TYPE_SEQUENCE:
677 fprintf(out,"type:SEQUENCE");break;
678 case TYPE_BIT_STRING:
679 fprintf(out,"type:BIT_STR");break;
680 case TYPE_OCTET_STRING:
681 fprintf(out,"type:OCT_STR");break;
682 case TYPE_GENERALSTRING:
683 fprintf(out,"type:GENERALSTRING");break;
684 case TYPE_SEQUENCE_OF:
685 fprintf(out,"type:SEQ_OF");break;
686 case TYPE_OBJECT_ID:
687 fprintf(out,"type:OBJ_ID");break;
688 case TYPE_ANY:
689 fprintf(out,"type:ANY");break;
690 case TYPE_SET:
691 fprintf(out,"type:SET");break;
692 case TYPE_SET_OF:
693 fprintf(out,"type:SET_OF");break;
694 case TYPE_CHOICE:
695 fprintf(out,"type:CHOICE");break;
696 case TYPE_DEFINITIONS:
697 fprintf(out,"type:DEFINITIONS");break;
698 default:
699 break;
703 if((mode == ASN1_PRINT_NAME_TYPE_VALUE) ||
704 (mode == ASN1_PRINT_ALL)){
705 switch(type_field(p->type)){
706 case TYPE_CONSTANT:
707 if(mode == ASN1_PRINT_ALL)
708 if(p->value) fprintf(out," value:%s",p->value);
709 break;
710 case TYPE_TAG:
711 if(mode == ASN1_PRINT_ALL)
712 if (p->value) fprintf(out," value:%s",p->value);
713 break;
714 case TYPE_SIZE:
715 if(mode == ASN1_PRINT_ALL)
716 if(p->value) fprintf(out," value:%s",p->value);
717 break;
718 case TYPE_DEFAULT:
719 if(p->value) fprintf(out," value:%s",p->value);
720 else if(p->type & CONST_TRUE) fprintf(out," value:TRUE");
721 else if(p->type & CONST_FALSE) fprintf(out," value:FALSE");
722 break;
723 case TYPE_IDENTIFIER:
724 if(p->value) fprintf(out," value:%s",p->value);
725 break;
726 case TYPE_INTEGER:
727 if(p->value){
728 len2=-1;
729 len=asn1_get_length_der(p->value,p->value_len,&len2);
730 fprintf(out," value:0x");
731 if (len > 0)
732 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
734 break;
735 case TYPE_ENUMERATED:
736 if(p->value){
737 len2=-1;
738 len=asn1_get_length_der(p->value,p->value_len,&len2);
739 fprintf(out," value:0x");
740 if (len > 0)
741 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
743 break;
744 case TYPE_TIME:
745 if(p->value) fprintf(out," value:%s",p->value);
746 break;
747 case TYPE_BOOLEAN:
748 if(p->value){
749 if(p->value[0]=='T') fprintf(out," value:TRUE");
750 else if(p->value[0]=='F') fprintf(out," value:FALSE");
752 break;
753 case TYPE_BIT_STRING:
754 if(p->value){
755 len2=-1;
756 len=asn1_get_length_der(p->value,p->value_len,&len2);
757 if (len>0)
759 fprintf(out," value(%i):",(len-1)*8-(p->value[len2]));
760 for(k=1;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
763 break;
764 case TYPE_OCTET_STRING:
765 if(p->value){
766 len2=-1;
767 len=asn1_get_length_der(p->value,p->value_len,&len2);
768 fprintf(out," value:");
769 if (len>0)
770 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
772 break;
773 case TYPE_GENERALSTRING:
774 if(p->value){
775 len2=-1;
776 len=asn1_get_length_der(p->value,p->value_len,&len2);
777 fprintf(out," value:");
778 if (len>0)
779 for(k=0;k<len;k++) fprintf(out,"%02x",(p->value)[k+len2]);
781 break;
782 case TYPE_OBJECT_ID:
783 if(p->value) fprintf(out," value:%s",p->value);
784 break;
785 case TYPE_ANY:
786 if(p->value){
787 len3=-1;
788 len2=asn1_get_length_der(p->value,p->value_len,&len3);
789 fprintf(out," value:");
790 if (len2>0)
791 for(k=0;k<len2;k++) fprintf(out,"%02x",(p->value)[k+len3]);
793 break;
794 case TYPE_SET:
795 case TYPE_SET_OF:
796 case TYPE_CHOICE:
797 case TYPE_DEFINITIONS:
798 case TYPE_SEQUENCE_OF:
799 case TYPE_SEQUENCE:
800 case TYPE_NULL:
801 break;
802 default:
803 break;
807 if(mode==ASN1_PRINT_ALL){
808 if(p->type&0x1FFFFF00){
809 fprintf(out," attr:");
810 if(p->type & CONST_UNIVERSAL) fprintf(out,"UNIVERSAL,");
811 if(p->type & CONST_PRIVATE) fprintf(out,"PRIVATE,");
812 if(p->type & CONST_APPLICATION) fprintf(out,"APPLICATION,");
813 if(p->type & CONST_EXPLICIT) fprintf(out,"EXPLICIT,");
814 if(p->type & CONST_IMPLICIT) fprintf(out,"IMPLICIT,");
815 if(p->type & CONST_TAG) fprintf(out,"TAG,");
816 if(p->type & CONST_DEFAULT) fprintf(out,"DEFAULT,");
817 if(p->type & CONST_TRUE) fprintf(out,"TRUE,");
818 if(p->type & CONST_FALSE) fprintf(out,"FALSE,");
819 if(p->type & CONST_LIST) fprintf(out,"LIST,");
820 if(p->type & CONST_MIN_MAX) fprintf(out,"MIN_MAX,");
821 if(p->type & CONST_OPTION) fprintf(out,"OPTION,");
822 if(p->type & CONST_1_PARAM) fprintf(out,"1_PARAM,");
823 if(p->type & CONST_SIZE) fprintf(out,"SIZE,");
824 if(p->type & CONST_DEFINED_BY) fprintf(out,"DEF_BY,");
825 if(p->type & CONST_GENERALIZED) fprintf(out,"GENERALIZED,");
826 if(p->type & CONST_UTC) fprintf(out,"UTC,");
827 if(p->type & CONST_SET) fprintf(out,"SET,");
828 if(p->type & CONST_NOT_USED) fprintf(out,"NOT_USED,");
829 if(p->type & CONST_ASSIGN) fprintf(out,"ASSIGNMENT,");
833 if(mode == ASN1_PRINT_ALL){
834 fprintf(out,"\n");
836 else{
837 switch(type_field(p->type)){
838 case TYPE_CONSTANT:
839 case TYPE_TAG:
840 case TYPE_SIZE:
841 break;
842 default:
843 fprintf(out,"\n");
847 if(p->down){
848 p=p->down;
849 indent+=2;
851 else if(p==root){
852 p=NULL;
853 break;
855 else if(p->right) p=p->right;
856 else{
857 while(1){
858 p=_asn1_find_up(p);
859 if(p==root){
860 p=NULL;
861 break;
863 indent-=2;
864 if(p->right){
865 p=p->right;
866 break;
876 * asn1_number_of_elements - Counts the number of elements of a structure.
877 * @element: pointer to the root of an ASN1 structure.
878 * @name: the name of a sub-structure of ROOT.
879 * @num: pointer to an integer where the result will be stored
881 * Counts the number of elements of a sub-structure called NAME with
882 * names equal to "?1","?2", ...
884 * Returns:
886 * ASN1_SUCCESS: Creation OK.
888 * ASN1_ELEMENT_NOT_FOUND: NAME isn't known.
890 * ASN1_GENERIC_ERROR: Pointer num equal to NULL.
893 asn1_retCode
894 asn1_number_of_elements(ASN1_TYPE element,const char *name,int *num)
896 node_asn *node,*p;
898 if(num==NULL) return ASN1_GENERIC_ERROR;
900 *num=0;
902 node=asn1_find_node(element,name);
903 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
905 p=node->down;
907 while(p){
908 if((p->name) && (p->name[0]=='?')) (*num)++;
909 p=p->right;
912 return ASN1_SUCCESS;
917 * asn1_find_structure_from_oid - Locate structure defined by a specific OID.
918 * @definitions: ASN1 definitions
919 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
921 * Search the structure that is defined just after an OID definition.
923 * Returns: NULL when OIDVALUE not found, otherwise the pointer to a
924 * constant string that contains the element name defined just
925 * after the OID.
928 const char*
929 asn1_find_structure_from_oid (ASN1_TYPE definitions,
930 const char *oidValue)
932 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1];
933 char value[MAX_NAME_SIZE];
934 ASN1_TYPE p;
935 int len;
936 asn1_retCode result;
938 if((definitions==ASN1_TYPE_EMPTY) || (oidValue==NULL))
939 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
942 strcpy(definitionsName,definitions->name);
943 strcat(definitionsName,".");
945 /* search the OBJECT_ID into definitions */
946 p=definitions->down;
947 while(p){
948 if((type_field(p->type)==TYPE_OBJECT_ID) &&
949 (p->type & CONST_ASSIGN)){
950 strcpy(name,definitionsName);
951 strcat(name,p->name);
953 len=MAX_NAME_SIZE;
954 result=asn1_read_value(definitions,name,value,&len);
956 if((result == ASN1_SUCCESS) && (!strcmp(oidValue,value))){
957 p=p->right;
958 if(p==NULL) /* reach the end of ASN1 definitions */
959 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
961 return p->name;
964 p=p->right;
967 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
971 * asn1_copy_node:
972 * @dst: Destination ASN1_TYPE node.
973 * @dst_name: Field name in destination node.
974 * @src: Source ASN1_TYPE node.
975 * @src_name: Field name in source node.
977 * Create a deep copy of a ASN1_TYPE variable.
979 * Return value: Return ASN1_SUCCESS on success.
981 asn1_retCode
982 asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
983 ASN1_TYPE src, const char *src_name)
986 int result;
987 ASN1_TYPE dst_node;
988 void *data = NULL;
989 int size = 0;
991 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
992 if (result != ASN1_MEM_ERROR)
993 return result;
995 data = _asn1_malloc (size);
996 if (data == NULL)
997 return ASN1_MEM_ERROR;
999 result = asn1_der_coding (src, src_name, data, &size, NULL);
1000 if (result != ASN1_SUCCESS)
1002 _asn1_free (data);
1003 return result;
1006 dst_node = asn1_find_node (dst, dst_name);
1007 if (dst_node == NULL)
1009 _asn1_free (data);
1010 return ASN1_ELEMENT_NOT_FOUND;
1013 result = asn1_der_decoding (&dst_node, data, size, NULL);
1015 _asn1_free (data);
1017 return result;