2 * Copyright (C) 2000,2001 Fabio Fiorina
4 * This file is part of GNUTLS.
6 * The GNUTLS 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
23 /*****************************************************/
24 /* File: x509_asn1.c */
25 /* Description: Functions to manage ASN.1 DEFINITIONS*/
26 /*****************************************************/
29 #include <gnutls_int.h>
30 #include <gnutls_errors.h>
31 #include "x509_asn1.h"
33 #include <gnutls_str.h>
35 /* define used for visiting trees */
41 int parse_mode
; /* PARSE_MODE_CHECK = only syntax check
42 PARSE_MODE_CREATE = structure creation */
45 /******************************************************/
46 /* Function : _asn1_add_node */
47 /* Description: creates a new NODE_ASN element. */
49 /* type: type of the new element (see TYPE_ */
50 /* and CONST_ constants). */
51 /* Return: pointer to the new element. */
52 /******************************************************/
54 _asn1_add_node(unsigned int type
)
58 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
60 punt
=(node_asn
*) gnutls_malloc(sizeof(node_asn
));
61 if (punt
==NULL
) return NULL
;
73 /******************************************************************/
74 /* Function : _asn1_set_value */
75 /* Description: sets the field VALUE in a NODE_ASN element. The */
76 /* previus value (if exist) will be lost */
78 /* node: element pointer. */
79 /* value: pointer to the value that you want to set. */
80 /* len: character number of value. */
81 /* Return: pointer to the NODE_ASN element. */
82 /******************************************************************/
84 _asn1_set_value(node_asn
*node
,unsigned char *value
,unsigned int len
)
86 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
88 if(node
==NULL
) return node
;
90 gnutls_free(node
->value
);
94 node
->value
=(unsigned char *) gnutls_malloc(len
);
95 if (node
->value
==NULL
) return NULL
;
97 memcpy(node
->value
,value
,len
);
101 /******************************************************************/
102 /* Function : _asn1_set_name */
103 /* Description: sets the field NAME in a NODE_ASN element. The */
104 /* previus value (if exist) will be lost */
106 /* node: element pointer. */
107 /* name: a null terminated string with the name that you want */
109 /* Return: pointer to the NODE_ASN element. */
110 /******************************************************************/
112 _asn1_set_name(node_asn
*node
,char *name
)
114 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
116 if(node
==NULL
) return node
;
119 gnutls_free(node
->name
);
123 if(name
==NULL
) return node
;
127 node
->name
=(char *) gnutls_strdup( name
);
128 if (node
->name
==NULL
) return NULL
;
130 else node
->name
=NULL
;
134 /******************************************************************/
135 /* Function : _asn1_set_right */
136 /* Description: sets the field RIGHT in a NODE_ASN element. */
138 /* node: element pointer. */
139 /* right: pointer to a NODE_ASN element that you want be pointed*/
141 /* Return: pointer to *NODE. */
142 /******************************************************************/
144 _asn1_set_right(node_asn
*node
,node_asn
*right
)
146 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
148 if(node
==NULL
) return node
;
150 if(right
) right
->left
=node
;
154 /******************************************************************/
155 /* Function : _asn1_get_right */
156 /* Description: returns the element pointed by the RIGHT field of */
157 /* a NODE_ASN element. */
159 /* node: NODE_ASN element pointer. */
160 /* Return: field RIGHT of NODE. */
161 /******************************************************************/
163 _asn1_get_right(node_asn
*node
)
165 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
167 if(node
==NULL
) return NULL
;
171 /******************************************************************/
172 /* Function : _asn1_get_last_right */
173 /* Description: return the last element along the right chain. */
175 /* node: starting element pointer. */
176 /* Return: pointer to the last element along the right chain. */
177 /******************************************************************/
179 _asn1_get_last_right(node_asn
*node
)
183 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
184 if(node
==NULL
) return NULL
;
186 while(p
->right
) p
=p
->right
;
190 /******************************************************************/
191 /* Function : _asn1_set_down */
192 /* Description: sets the field DOWN in a NODE_ASN element. */
194 /* node: element pointer. */
195 /* down: pointer to a NODE_ASN element that you want be pointed */
197 /* Return: pointer to *NODE. */
198 /******************************************************************/
200 _asn1_set_down(node_asn
*node
,node_asn
*down
)
202 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
204 if(node
==NULL
) return node
;
206 if(down
) down
->left
=node
;
210 /******************************************************************/
211 /* Function : _asn1_get_down */
212 /* Description: returns the element pointed by the DOWN field of */
213 /* a NODE_ASN element. */
215 /* node: NODE_ASN element pointer. */
216 /* Return: field DOWN of NODE. */
217 /******************************************************************/
219 _asn1_get_down(node_asn
*node
)
221 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
223 if(node
==NULL
) return NULL
;
227 /******************************************************************/
228 /* Function : _asn1_get_name */
229 /* Description: returns the name of a NODE_ASN element. */
231 /* node: NODE_ASN element pointer. */
232 /* Return: a null terminated string. */
233 /******************************************************************/
235 _asn1_get_name(node_asn
*node
)
237 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
239 if(node
==NULL
) return NULL
;
243 /******************************************************************/
244 /* Function : _asn1_mod_type */
245 /* Description: change the field TYPE of an NODE_ASN element. */
246 /* The new value is the old one | (bitwise or) the */
247 /* paramener VALUE. */
249 /* node: NODE_ASN element pointer. */
250 /* value: the integer value that must be or-ed with the current */
251 /* value of field TYPE. */
252 /* Return: NODE pointer. */
253 /******************************************************************/
255 _asn1_mod_type(node_asn
*node
,unsigned int value
)
257 if(parse_mode
==PARSE_MODE_CHECK
) return NULL
;
259 if(node
==NULL
) return node
;
264 /******************************************************************/
265 /* Function : _asn1_remove_node */
266 /* Description: gets free the memory allocated for an NODE_ASN */
267 /* element (not the elements pointed by it). */
269 /* node: NODE_ASN element pointer. */
270 /******************************************************************/
272 _asn1_remove_node(node_asn
*node
)
274 if(node
==NULL
) return;
276 if (node
->name
!=NULL
)
277 gnutls_free(node
->name
);
278 if (node
->value
!=NULL
)
279 gnutls_free(node
->value
);
284 /******************************************************************/
285 /* Function : _asn1_find_mode */
286 /* Description: searches an element called NAME starting from */
287 /* POINTER. The name is composed by differents */
288 /* identifiers separated by dot.The first identifier */
289 /* must be the name of *POINTER. */
291 /* pointer: NODE_ASN element pointer. */
292 /* name: null terminated string with the element's name to find.*/
293 /* Return: the searching result. NULL if not find. */
294 /******************************************************************/
296 _asn1_find_node(node_asn
*pointer
,char *name
)
299 char *n_start
,*n_end
,n
[128];
301 if((name
==NULL
) || (name
[0]==0)) return NULL
;
304 n_end
=strchr(n_start
,'.'); /* search the first dot */
306 memcpy(n
,n_start
,n_end
-n_start
);
312 _gnutls_str_cpy(n
,sizeof(n
),n_start
);
318 if((p
->name
) && (!strcmp(p
->name
,n
))) break;
322 if(p
==NULL
) return NULL
;
324 while(n_start
){ /* Has the end of NAME been reached? */
325 n_end
=strchr(n_start
,'.'); /* search the next dot */
327 memcpy(n
,n_start
,n_end
-n_start
);
333 _gnutls_str_cpy(n
,sizeof(n
),n_start
);
337 if(p
->down
==NULL
) return NULL
;
341 /* The identifier "?LAST" indicates the last element
342 in the right chain. */
343 if(!strcmp(n
,"?LAST")){
344 if(p
==NULL
) return NULL
;
345 while(p
->right
) p
=p
->right
;
347 else{ /* no "?LAST" */
349 if((p
->name
) && (!strcmp(p
->name
,n
))) break;
352 if(p
==NULL
) return NULL
;
359 /******************************************************************/
360 /* Function : _asn1_find_left */
361 /* Description: returns the NODE_ASN element with RIGHT field that*/
362 /* points the element NODE. */
364 /* node: NODE_ASN element pointer. */
365 /* Return: NULL if not found. */
366 /******************************************************************/
368 _asn1_find_left(node_asn
*node
)
370 if((node
==NULL
) || (node
->left
==NULL
) ||
371 (node
->left
->down
==node
)) return NULL
;
376 /******************************************************************/
377 /* Function : _asn1_find_up */
378 /* Description: return the father of the NODE_ASN element. */
380 /* node: NODE_ASN element pointer. */
381 /* Return: Null if not found. */
382 /******************************************************************/
384 _asn1_find_up(node_asn
*node
)
388 if(node
==NULL
) return NULL
;
392 while((p
->left
!=NULL
) && (p
->left
->right
==p
)) p
=p
->left
;
397 /******************************************************************/
398 /* Function : _asn1_convert_integer */
399 /* Description: converts an integer from a null terminated string */
400 /* to der decoding. The convertion from a null */
401 /* terminated string to an integer is made with */
402 /* the 'strtol' function. */
404 /* value: null terminated string to convert. */
405 /* value_out: convertion result (memory must be already */
407 /* value_out_size: number of bytes of value_out. */
408 /* len: number of significant byte of value_out. */
409 /* Return: ASN_MEM_ERROR or ASN_OK */
410 /******************************************************************/
412 _asn1_convert_integer(char *value
,unsigned char *value_out
,int value_out_size
, int *len
)
415 unsigned char val
[4],temp
;
418 *((long*)val
)=strtol(value
,NULL
,10);
425 if(val
[0]&0x80) negative
=1;
429 if(negative
&& (val
[k
]!=0xFF)) break;
430 else if(!negative
&& val
[k
]) break;
433 if((negative
&& !(val
[k
]&0x80)) ||
434 (!negative
&& (val
[k
]&0x80))) k
--;
436 for(k2
=k
;k2
<4;k2
++) {
437 if (k2
-k
> value_out_size
-1) {
439 return ASN_MEM_ERROR
;
441 /* VALUE_OUT is too short to contain the value convertion */
442 value_out
[k2
-k
]=val
[k2
];
450 * asn1_create_tree - Creates the structures needed to manage the ASN1 definitions.
451 * @root: specify vector that contains ASN.1 declarations
452 * @pointer: return the pointer to the structure created by *ROOT ASN.1 declarations
455 * Creates the structures needed to manage the ASN1 definitions. ROOT is a vector created by
456 * 'asn1_parser_asn1_file_c' function.
460 * ASN_OK\: structure created correctly.
462 * ASN_GENERIC_ERROR\: an error occured while structure creation
465 asn1_create_tree(const static_asn
*root
,node_asn
**pointer
)
475 while(root
[k
].value
|| root
[k
].type
|| root
[k
].name
){
476 p
=_asn1_add_node(root
[k
].type
&(~CONST_DOWN
));
477 if(root
[k
].name
) _asn1_set_name(p
,root
[k
].name
);
478 if(root
[k
].value
) _asn1_set_value(p
,root
[k
].value
,strlen(root
[k
].value
)+1);
480 if(*pointer
==NULL
) *pointer
=p
;
482 if(move
==DOWN
) _asn1_set_down(p_last
,p
);
483 else if(move
==RIGHT
) _asn1_set_right(p_last
,p
);
487 if(root
[k
].type
&CONST_DOWN
) move
=DOWN
;
488 else if(root
[k
].type
&CONST_RIGHT
) move
=RIGHT
;
491 if(p_last
==*pointer
) break;
493 p_last
= _asn1_find_up(p_last
);
495 if(p_last
==NULL
) break;
497 if(p_last
->type
&CONST_RIGHT
){
498 p_last
->type
&=~CONST_RIGHT
;
507 if(p_last
==*pointer
){
508 _asn1_change_integer_value(*pointer
);
509 _asn1_expand_object_id(*pointer
);
511 else asn1_delete_structure(*pointer
);
513 return (p_last
==*pointer
)?ASN_OK
:ASN_GENERIC_ERROR
;
518 _asn1_create_static_structure(node_asn
*pointer
,char *file_name
, char* out_name
)
523 char structure_name
[128],file_out_name
[128],*char_p
,*slash_p
,*dot_p
;
527 while((char_p
=strchr(char_p
,'/'))){
533 dot_p
=file_name
+strlen(file_name
);
535 while((char_p
=strchr(char_p
,'.'))){
540 memcpy(structure_name
,slash_p
,dot_p
-slash_p
);
541 structure_name
[dot_p
-slash_p
]=0;
542 _gnutls_str_cat(structure_name
, sizeof(structure_name
),"_asn1_tab");
544 if (out_name
==NULL
) {
545 memcpy(file_out_name
,file_name
,dot_p
-file_name
);
546 file_out_name
[dot_p
-file_name
]=0;
547 _gnutls_str_cat(file_out_name
, sizeof(file_out_name
), "_asn1_tab.c");
549 _gnutls_str_cpy( file_out_name
, sizeof(file_out_name
), out_name
);
551 file
=fopen( file_out_name
,"w");
553 if(file
==NULL
) return ASN_FILE_NOT_FOUND
;
555 fprintf(file
,"\n#include \"x509_asn1.h\"\n\n");
556 fprintf(file
,"const static_asn %s[]={\n",structure_name
);
563 if(p
->name
) fprintf(file
,"\"%s\",",p
->name
);
564 else fprintf(file
,"0,");
567 if(p
->down
) t
|=CONST_DOWN
;
568 if(p
->right
) t
|=CONST_RIGHT
;
570 fprintf(file
,"%lu,",t
);
572 if(p
->value
) fprintf(file
,"\"%s\"},\n",p
->value
);
573 else fprintf(file
,"0},\n");
596 fprintf(file
," {0,0,0}\n};\n");
605 * asn1_visit_tree - Prints on the standard output the structure's tree
606 * @pointer: pointer to the structure that you want to delete.
607 * @name: an element of the structure
609 * Prints on the standard output the structure's tree starting from the NAME element inside
610 * the structure *POINTER.
613 asn1_visit_tree(node_asn
*pointer
,char *name
)
616 int k
,indent
=0,len
,len2
,len3
;
618 root
=_asn1_find_node(pointer
,name
);
620 if(root
==NULL
) return;
624 for(k
=0;k
<indent
;k
++)printf(" ");
627 if(p
->name
) printf("%s ",p
->name
);
628 else printf("NULL ");
631 switch(type_field(p
->type
)){
637 if(p
->value
) printf(" value:%s",p
->value
);
639 case TYPE_IDENTIFIER
:
640 printf("IDENTIFIER");
641 if(p
->value
) printf(" value:%s",p
->value
);
647 len
=_asn1_get_length_der(p
->value
,&len2
);
649 for(k
=0;k
<len
;k
++) printf("%02x",(p
->value
)[k
+len2
]);
652 case TYPE_ENUMERATED
:
653 printf("ENUMERATED");
656 len
=_asn1_get_length_der(p
->value
,&len2
);
658 for(k
=0;k
<len
;k
++) printf("%02x",(p
->value
)[k
+len2
]);
663 if(p
->value
) printf(" value:%s",p
->value
);
668 if(p
->value
[0]=='T') printf(" value:TRUE");
669 else if(p
->value
[0]=='F') printf(" value:FALSE");
675 case TYPE_BIT_STRING
:
679 len
=_asn1_get_length_der(p
->value
,&len2
);
680 printf(" value(%i):",(len
-1)*8-(p
->value
[len2
]));
681 for(k
=1;k
<len
;k
++) printf("%02x",(p
->value
)[k
+len2
]);
684 case TYPE_OCTET_STRING
:
688 len
=_asn1_get_length_der(p
->value
,&len2
);
690 for(k
=0;k
<len
;k
++) printf("%02x",(p
->value
)[k
+len2
]);
695 printf(" value:%s",p
->value
);
699 if(p
->value
) printf(" value:%s",p
->value
);
703 if(p
->value
) printf(" value:%s",p
->value
);
705 case TYPE_SEQUENCE_OF
:
710 if(p
->value
) printf(" value:%s",p
->value
);
716 len2
=_asn1_get_length_der(p
->value
,&len3
);
718 for(k
=0;k
<len2
;k
++) printf("%02x",(p
->value
)[k
+len3
]);
731 case TYPE_DEFINITIONS
:
732 printf("DEFINITIONS");
739 if(p
->type
&0xFFFFFF00){
741 if(p
->type
& CONST_UNIVERSAL
) printf("UNIVERSAL,");
742 if(p
->type
& CONST_PRIVATE
) printf("PRIVATE,");
743 if(p
->type
& CONST_APPLICATION
) printf("APPLICATION,");
744 if(p
->type
& CONST_EXPLICIT
) printf("EXPLICIT,");
745 if(p
->type
& CONST_IMPLICIT
) printf("IMPLICIT,");
746 if(p
->type
& CONST_TAG
) printf("TAG,");
747 if(p
->type
& CONST_DEFAULT
) printf("DEFAULT,");
748 if(p
->type
& CONST_TRUE
) printf("TRUE,");
749 if(p
->type
& CONST_FALSE
) printf("FALSE,");
750 if(p
->type
& CONST_LIST
) printf("LIST,");
751 if(p
->type
& CONST_MIN_MAX
) printf("MIN_MAX,");
752 if(p
->type
& CONST_OPTION
) printf("OPTION,");
753 if(p
->type
& CONST_1_PARAM
) printf("1_PARAM,");
754 if(p
->type
& CONST_SIZE
) printf("SIZE,");
755 if(p
->type
& CONST_DEFINED_BY
) printf("DEF_BY,");
756 if(p
->type
& CONST_GENERALIZED
) printf("GENERALIZED,");
757 if(p
->type
& CONST_UTC
) printf("UTC,");
758 if(p
->type
& CONST_IMPORTS
) printf("IMPORTS,");
759 if(p
->type
& CONST_SET
) printf("SET,");
760 if(p
->type
& CONST_NOT_USED
) printf("NOT_USED,");
761 if(p
->type
& CONST_ASSIGN
) printf("ASSIGNEMENT,");
774 else if(p
->right
) p
=p
->right
;
794 * asn1_delete_structure - Deletes the structure *POINTER.
795 * @root: pointer to the structure that you want to delete.
798 * Deletes the structure *POINTER.
802 * ASN_OK\: everything OK
804 * ASN_ELEMENT_NOT_FOUND\: pointer==NULL.
808 asn1_delete_structure(node_asn
*root
)
812 if(root
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
823 _asn1_set_down(p3
,p2
);
824 _asn1_remove_node(p
);
828 p3
=_asn1_find_left(p
);
831 if(p3
) _asn1_set_down(p3
,p2
);
833 if(p
->right
) p
->right
->left
=NULL
;
836 else _asn1_set_right(p3
,p2
);
837 _asn1_remove_node(p
);
847 _asn1_copy_structure3(node_asn
*source_node
)
849 node_asn
*dest_node
,*p_s
,*p_d
,*p_d_prev
;
852 if(source_node
==NULL
) return NULL
;
854 dest_node
=_asn1_add_node(source_node
->type
);
863 if(p_s
->name
) _asn1_set_name(p_d
,p_s
->name
);
865 switch(type_field(p_s
->type
)){
866 case TYPE_OCTET_STRING
: case TYPE_BIT_STRING
:
867 case TYPE_INTEGER
: // case TYPE_DEFAULT:
869 len
=_asn1_get_length_der(p_s
->value
,&len2
);
870 _asn1_set_value(p_d
,p_s
->value
,len
+len2
);
873 _asn1_set_value(p_d
,p_s
->value
,strlen(p_s
->value
)+1);
884 p_d
=_asn1_add_node(p_s
->type
);
885 _asn1_set_down(p_d_prev
,p_d
);
890 if(p_s
==source_node
) break;
896 p_d
=_asn1_add_node(p_s
->type
);
897 _asn1_set_right(p_d_prev
,p_d
);
902 p_s
=_asn1_find_up(p_s
);
903 p_d
=_asn1_find_up(p_d
);
905 }while(p_s
!=source_node
);
912 _asn1_copy_structure2(node_asn
*root
,char *source_name
)
914 node_asn
*source_node
;
916 source_node
=_asn1_find_node(root
,source_name
);
918 return _asn1_copy_structure3(source_node
);
924 * asn1_create_structure - Creates a structure called DEST_NAME of type SOURCE_NAME.
925 * @root: pointer to the structure returned by "parser_asn1" function
926 * @source_name: the name of the type of the new structure (must be inside p_structure).
927 * @pointer: pointer to the structure created.
928 * @dest_name: the name of the new structure.
931 * Creates a structure called DEST_NAME of type SOURCE_NAME.
935 * ASN_OK\: creation OK
937 * ASN_ELEMENT_NOT_FOUND\: SOURCE_NAME isn't known
939 * Example: using "pkix.asn"
940 * result=asn1_create_structure(cert_def,"PKIX1.Certificate",&cert,"certificate1");
943 asn1_create_structure(node_asn
*root
,char *source_name
,node_asn
**pointer
,char *dest_name
)
951 dest_node
=_asn1_copy_structure2(root
,source_name
);
953 if(dest_node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
955 _asn1_set_name(dest_node
,dest_name
);
957 end
=strchr(source_name
,'.');
959 memcpy(n
,source_name
,end
-source_name
);
960 n
[end
-source_name
]=0;
963 _gnutls_str_cpy(n
,sizeof(n
),source_name
);
966 res
=_asn1_expand_identifier(&dest_node
,root
);
967 _asn1_type_choice_config(dest_node
);
976 _asn1_append_sequence_set(node_asn
*node
)
982 if(!node
|| !(node
->down
)) return ASN_GENERIC_ERROR
;
985 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
986 p2
=_asn1_copy_structure3(p
);
987 while(p
->right
) p
=p
->right
;
988 _asn1_set_right(p
,p2
);
990 if(p
->name
==NULL
) _gnutls_str_cpy(temp
,sizeof(temp
),"?1");
992 n
=strtol(p
->name
+1,NULL
,0);
995 _asn1_ltostr(n
,temp
+1);
997 _asn1_set_name(p2
,temp
);
1004 * asn1_write_value - Set the value of one element inside a structure.
1005 * @node_root: pointer to a structure
1006 * @name: the name of the element inside the structure that you want to set.
1007 * @value: vector used to specify the value to set. If len is >0,
1008 * VALUE must be a two's complement form integer.
1009 * if len=0 *VALUE must be a null terminated string with an integer value.
1010 * @len: number of bytes of *value to use to set the value: value[0]..value[len-1]
1011 * or 0 if value is a null terminated string
1014 * Set the value of one element inside a structure.
1018 * ASN_OK\: set value OK
1020 * ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
1022 * ASN_VALUE_NOT_VALID\: VALUE has a wrong format.
1025 * description for each type
1026 * INTEGER: VALUE must contain a two's complement form integer.
1027 * value[0]=0xFF , len=1 -> integer=-1
1028 * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1
1029 * value[0]=0x01 , len=1 -> integer= 1
1030 * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1
1031 * value="123" , len=0 -> integer= 123
1032 * ENUMERATED: as INTEGER (but only with not negative numbers)
1033 * BOOLEAN: VALUE must be the null terminated string "TRUE" or "FALSE" and LEN != 0
1034 * value="TRUE" , len=1 -> boolean=TRUE
1035 * value="FALSE" , len=1 -> boolean=FALSE
1036 * OBJECT IDENTIFIER: VALUE must be a null terminated string with each number separated by
1037 * a blank (e.g. "1 2 3 543 1").
1039 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha
1040 * UTCTime: VALUE must be a null terminated string in one of these formats:
1041 * "YYMMDDhhmmssZ" "YYMMDDhhmmssZ" "YYMMDDhhmmss+hh'mm'" "YYMMDDhhmmss-hh'mm'"
1042 * "YYMMDDhhmm+hh'mm'" "YYMMDDhhmm-hh'mm'".
1044 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998 at 12h 00m Greenwich Mean Time
1045 * GeneralizedTime: VALUE must be in one of this format:
1046 * "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.s+hh'mm'"
1047 * "YYYYMMDDhhmmss.s-hh'mm'" "YYYYMMDDhhmm+hh'mm'" "YYYYMMDDhhmm-hh'mm'"
1048 * where ss.s indicates the seconds with any precision like "10.1" or "01.02".
1050 * value="2001010112001.12-0700" , len=1 -> time=Jannuary 1st, 2001 at 12h 00m 01.12s
1051 * Pacific Daylight Time
1052 * OCTET STRING: VALUE contains the octet string and LEN is the number of octet.
1053 * value="$\backslash$x01$\backslash$x02$\backslash$x03" , len=3 -> three bytes octet string
1054 * BIT STRING: VALUE contains the bit string organized by bytes and LEN is the number of bits.
1055 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six bits)
1056 * CHOICE: if NAME indicates a choice type, VALUE must specify one of the alternatives with a
1057 * null terminated string. LEN != 0
1059 * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);
1060 * ANY: VALUE indicates the der encoding of a structure.
1062 * SEQUENCE OF: VALUE must be the null terminated string "NEW" and LEN != 0. With this
1063 * instruction another element is appended in the sequence. The name of this
1064 * element will be "?1" if it's the first one, "?2" for the second and so on.
1066 * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);
1067 * SET OF: the same as SEQUENCE OF.
1069 * result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",1);
1071 * If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0.
1073 * result=asn1_write_value(cert,"certificate1.tbsCertificate.issuerUniqueID",NULL,0);
1077 asn1_write_value(node_asn
*node_root
,char *name
,unsigned char *value
,int len
)
1079 node_asn
*node
,*p
,*p2
;
1080 unsigned char *temp
,*value_temp
,*default_temp
;
1081 int len2
,k
,k2
,negative
;
1083 node
=_asn1_find_node(node_root
,name
);
1084 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1086 if((node
->type
& CONST_OPTION
) && (value
==NULL
) && (len
==0)){
1087 asn1_delete_structure(node
);
1091 switch(type_field(node
->type
)){
1093 if(!strcmp(value
,"TRUE")){
1094 if(node
->type
&CONST_DEFAULT
){
1096 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
1097 if(p
->type
&CONST_TRUE
) _asn1_set_value(node
,NULL
,0);
1098 else _asn1_set_value(node
,"T",1);
1100 else _asn1_set_value(node
,"T",1);
1102 else if(!strcmp(value
,"FALSE")){
1103 if(node
->type
&CONST_DEFAULT
){
1105 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
1106 if(p
->type
&CONST_FALSE
) _asn1_set_value(node
,NULL
,0);
1107 else _asn1_set_value(node
,"F",1);
1109 else _asn1_set_value(node
,"F",1);
1111 else return ASN_VALUE_NOT_VALID
;
1113 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
1115 if(isdigit(value
[0])){
1116 value_temp
=(unsigned char *)gnutls_alloca(4);
1117 if (value_temp
==NULL
) return ASN_MEM_ERROR
;
1119 _asn1_convert_integer(value
,value_temp
,4, &len
);
1121 else{ /* is an identifier like v1 */
1122 if(!(node
->type
&CONST_LIST
)) return ASN_VALUE_NOT_VALID
;
1125 if(type_field(p
->type
)==TYPE_CONSTANT
){
1126 if((p
->name
) && (!strcmp(p
->name
,value
))){
1127 value_temp
=(unsigned char *)gnutls_alloca(4);
1128 if (value_temp
==NULL
) return ASN_MEM_ERROR
;
1130 _asn1_convert_integer(p
->value
,value_temp
,4, &len
);
1136 if(p
==NULL
) return ASN_VALUE_NOT_VALID
;
1140 value_temp
=(unsigned char *)gnutls_alloca(len
);
1141 if (value_temp
==NULL
) return ASN_MEM_ERROR
;
1142 memcpy(value_temp
,value
,len
);
1146 if(value_temp
[0]&0x80) negative
=1;
1149 if(negative
&& (type_field(node
->type
)==TYPE_ENUMERATED
))
1150 {gnutls_afree(value_temp
);return ASN_VALUE_NOT_VALID
;}
1152 for(k
=0;k
<len
-1;k
++)
1153 if(negative
&& (value_temp
[k
]!=0xFF)) break;
1154 else if(!negative
&& value_temp
[k
]) break;
1156 if((negative
&& !(value_temp
[k
]&0x80)) ||
1157 (!negative
&& (value_temp
[k
]&0x80))) k
--;
1159 _asn1_length_der(len
-k
,NULL
,&len2
);
1160 temp
=(unsigned char *)gnutls_alloca(len
-k
+len2
);
1161 if (temp
==NULL
) return ASN_MEM_ERROR
;
1163 _asn1_octet_der(value_temp
+k
,len
-k
,temp
,&len2
);
1164 _asn1_set_value(node
,temp
,len2
);
1168 if(node
->type
&CONST_DEFAULT
){
1170 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
1171 if(isdigit(p
->value
[0])){
1172 default_temp
=(unsigned char *)gnutls_alloca(4);
1173 if (default_temp
==NULL
) return ASN_MEM_ERROR
;
1175 _asn1_convert_integer(p
->value
,default_temp
,4,&len2
);
1177 else{ /* is an identifier like v1 */
1178 if(!(node
->type
&CONST_LIST
)) return ASN_VALUE_NOT_VALID
;
1181 if(type_field(p2
->type
)==TYPE_CONSTANT
){
1182 if((p2
->name
) && (!strcmp(p2
->name
,p
->value
))){
1183 default_temp
=(unsigned char *)gnutls_alloca(4);
1184 if (default_temp
==NULL
) return ASN_MEM_ERROR
;
1186 _asn1_convert_integer(p2
->value
,default_temp
,4,&len2
);
1192 if(p2
==NULL
) return ASN_VALUE_NOT_VALID
;
1196 for(k2
=0;k2
<len2
;k2
++)
1197 if(value_temp
[k
+k2
]!=default_temp
[k2
]){
1200 if(k2
==len2
) _asn1_set_value(node
,NULL
,0);
1202 gnutls_afree(default_temp
);
1204 gnutls_afree(value_temp
);
1206 case TYPE_OBJECT_ID
:
1207 for(k
=0;k
<strlen(value
);k
++)
1208 if((!isdigit(value
[k
])) && (value
[k
]!=' ') && (value
[k
]!='+'))
1209 return ASN_VALUE_NOT_VALID
;
1210 _asn1_set_value(node
,value
,strlen(value
)+1);
1213 if(node
->type
&CONST_UTC
){
1214 if(strlen(value
)<11) return ASN_VALUE_NOT_VALID
;
1216 if(!isdigit(value
[k
])) return ASN_VALUE_NOT_VALID
;
1217 switch(strlen(value
)){
1219 if(value
[10]!='Z') return ASN_VALUE_NOT_VALID
;
1222 if((!isdigit(value
[10])) || (!isdigit(value
[11])) ||
1223 (value
[12]!='Z')) return ASN_VALUE_NOT_VALID
;
1226 if((value
[10]!='+') && (value
[10]!='-')) return ASN_VALUE_NOT_VALID
;
1228 if(!isdigit(value
[k
])) return ASN_VALUE_NOT_VALID
;
1231 if((!isdigit(value
[10])) || (!isdigit(value
[11])))
1232 return ASN_VALUE_NOT_VALID
;
1233 if((value
[12]!='+') && (value
[12]!='-')) return ASN_VALUE_NOT_VALID
;
1235 if(!isdigit(value
[k
])) return ASN_VALUE_NOT_VALID
;
1238 return ASN_VALUE_NOT_FOUND
;
1240 _asn1_set_value(node
,value
,strlen(value
)+1);
1242 else{ /* GENERALIZED TIME */
1243 if(value
) _asn1_set_value(node
,value
,strlen(value
)+1);
1246 case TYPE_OCTET_STRING
:
1247 _asn1_length_der(len
,NULL
,&len2
);
1248 temp
=(unsigned char *)gnutls_alloca(len
+len2
);
1249 if (temp
==NULL
) return ASN_MEM_ERROR
;
1251 _asn1_octet_der(value
,len
,temp
,&len2
);
1252 _asn1_set_value(node
,temp
,len2
);
1255 case TYPE_BIT_STRING
:
1256 _asn1_length_der((len
>>3)+2,NULL
,&len2
);
1257 temp
=(unsigned char *)gnutls_alloca((len
>>3)+2+len2
);
1258 if (temp
==NULL
) return ASN_MEM_ERROR
;
1260 _asn1_bit_der(value
,len
,temp
,&len2
);
1261 _asn1_set_value(node
,temp
,len2
);
1267 if(!strcmp(p
->name
,value
)){
1270 if(p2
!=p
){asn1_delete_structure(p2
); p2
=node
->down
;}
1277 if(!p
) return ASN_ELEMENT_NOT_FOUND
;
1280 _asn1_length_der(len
,NULL
,&len2
);
1281 temp
=(unsigned char *)gnutls_alloca(len
+len2
);
1282 if (temp
==NULL
) return ASN_MEM_ERROR
;
1284 _asn1_octet_der(value
,len
,temp
,&len2
);
1285 _asn1_set_value(node
,temp
,len2
);
1288 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
1289 if(strcmp(value
,"NEW")) return ASN_VALUE_NOT_VALID
;
1290 _asn1_append_sequence_set(node
);
1293 return ASN_ELEMENT_NOT_FOUND
;
1300 #define PUT_VALUE( ptr, ptr_size, data, data_size) \
1302 if (ptr_size < data_size) { \
1304 return ASN_MEM_ERROR; \
1306 memcpy( ptr, data, data_size); \
1309 #define PUT_STR_VALUE( ptr, ptr_size, data) \
1310 *len = strlen(data) + 1; \
1311 if (ptr_size < *len) { \
1313 return ASN_MEM_ERROR; \
1315 /* this strcpy is checked */ \
1316 strcpy(ptr, data); \
1319 #define ADD_STR_VALUE( ptr, ptr_size, data) \
1320 *len = strlen(data) + 1; \
1321 if (ptr_size < strlen(ptr)+(*len)) { \
1323 return ASN_MEM_ERROR; \
1325 /* this strcat is checked */ \
1326 strcat(ptr, data); \
1330 * asn1_read_value - Returns the value of one element inside a structure
1331 * @root: pointer to a structure
1332 * @name: the name of the element inside a structure that you want to read.
1333 * @value: vector that will contain the element's content.
1334 * VALUE must be a pointer to memory cells already allocated.
1335 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy holds the sizeof value.
1339 * Returns the value of one element inside a structure.
1343 * ASN_OK\: set value OK
1345 * ASN_ELEMENT_NOT_FOUND\: NAME is not a valid element.
1347 * ASN_VALUE_NOT_FOUND\: there isn't any value for the element selected.
1350 * a description for each type
1351 * INTEGER: VALUE will contain a two's complement form integer.
1352 * integer=-1 -> value[0]=0xFF , len=1
1353 * integer=1 -> value[0]=0x01 , len=1
1354 * ENUMERATED: as INTEGER (but only with not negative numbers)
1355 * BOOLEAN: VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6
1356 * OBJECT IDENTIFIER: VALUE will be a null terminated string with each number separated by
1357 * a blank (i.e. "1 2 3 543 1").
1358 * LEN = strlen(VALUE)+1
1359 * UTCTime: VALUE will be a null terminated string in one of these formats:
1360 * "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'"
1361 * LEN=strlen(VALUE)+1
1362 * GeneralizedTime: VALUE will be a null terminated string in the same format used to set
1364 * OCTET STRING: VALUE will contain the octet string and LEN will be the number of octet.
1365 * BIT STRING: VALUE will contain the bit string organized by bytes and LEN will be the
1367 * CHOICE: if NAME indicates a choice type, VALUE will specify the alternative selected
1368 * ANY: if NAME indicates an any type, VALUE will indicate the DER encoding of the structure
1371 * If an element is OPTIONAL and the function "read_value" returns ASN_ELEMENT_NOT_FOUND, it
1372 * means that this element wasn't present in the der encoding that created the structure.
1373 * The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.
1377 asn1_read_value(node_asn
*root
,char *name
,unsigned char *value
, int *len
)
1381 int value_size
= *len
;
1383 node
=_asn1_find_node(root
,name
);
1384 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1386 if((type_field(node
->type
)!=TYPE_NULL
) &&
1387 (type_field(node
->type
)!=TYPE_CHOICE
) &&
1388 !(node
->type
&CONST_DEFAULT
) && !(node
->type
&CONST_ASSIGN
) &&
1389 (node
->value
==NULL
))
1390 return ASN_VALUE_NOT_FOUND
;
1392 switch(type_field(node
->type
)){
1394 PUT_STR_VALUE( value
, value_size
, "NULL");
1397 if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
1399 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
1400 if(p
->type
&CONST_TRUE
) {
1401 PUT_STR_VALUE( value
, value_size
, "TRUE");
1403 PUT_STR_VALUE(value
, value_size
, "FALSE");
1406 else if(node
->value
[0]=='T') {
1407 PUT_STR_VALUE(value
, value_size
, "TRUE");
1410 PUT_STR_VALUE(value
, value_size
, "FALSE");
1413 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
1414 if((node
->type
&CONST_DEFAULT
) && (node
->value
==NULL
)){
1416 while(type_field(p
->type
)!=TYPE_DEFAULT
) p
=p
->right
;
1417 if (_asn1_convert_integer(p
->value
,value
,value_size
, len
)!=ASN_OK
) return ASN_MEM_ERROR
;
1421 if (_asn1_get_octet_der(node
->value
,&len2
,value
, value_size
, len
)!=ASN_OK
) return ASN_MEM_ERROR
;
1424 case TYPE_OBJECT_ID
:
1425 if(node
->type
&CONST_ASSIGN
){
1426 _gnutls_str_cpy(value
, *len
, "");
1429 if(type_field(p
->type
)==TYPE_CONSTANT
){
1430 ADD_STR_VALUE( value
, value_size
, p
->value
);
1432 ADD_STR_VALUE( value
, value_size
, " ");
1438 PUT_STR_VALUE(value
, value_size
, node
->value
);
1442 PUT_STR_VALUE( value
, value_size
, node
->value
);
1444 case TYPE_OCTET_STRING
:
1446 if (_asn1_get_octet_der(node
->value
,&len2
,value
, value_size
, len
)!=ASN_OK
) return ASN_MEM_ERROR
;
1448 case TYPE_BIT_STRING
:
1450 if (_asn1_get_bit_der(node
->value
,&len2
,value
,value_size
,len
)!=ASN_OK
) return ASN_MEM_ERROR
;
1453 PUT_STR_VALUE( value
, value_size
, node
->down
->name
);
1457 len2
=_asn1_get_length_der(node
->value
,&len3
);
1458 PUT_VALUE( value
, value_size
, node
->value
+len3
, len2
);
1461 return ASN_ELEMENT_NOT_FOUND
;
1468 * asn1_number_of_elements - Counts the number of elements of a structure.
1469 * @root: pointer to the root of an ASN1 structure.
1470 * @name: the name of a sub-structure of ROOT.
1471 * @num: pointer to an integer where the result will be stored
1474 * Counts the number of elements of a sub-structure called NAME with names equal to "?1","?2", ...
1478 * ASN_OK: creation OK
1479 * ASN_ELEMENT_NOT_FOUND: NAME isn't known
1480 * ASN_GENERIC_ERROR: parameter num equal to NULL
1484 asn1_number_of_elements(node_asn
*root
,char *name
,int *num
)
1488 if(num
==NULL
) return ASN_GENERIC_ERROR
;
1492 node
=_asn1_find_node(root
,name
);
1493 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1498 if((p
->name
) && (p
->name
[0]=='?')) (*num
)++;
1507 _asn1_set_default_tag(node_asn
*node
)
1511 if((node
==NULL
) || (type_field(node
->type
)!=TYPE_DEFINITIONS
))
1512 return ASN_ELEMENT_NOT_FOUND
;
1516 if((type_field(p
->type
)==TYPE_TAG
) &&
1517 !(p
->type
&CONST_EXPLICIT
) &&
1518 !(p
->type
&CONST_IMPLICIT
)){
1519 if(node
->type
&CONST_EXPLICIT
) p
->type
|=CONST_EXPLICIT
;
1520 else p
->type
|=CONST_IMPLICIT
;
1526 else if(p
->right
) p
=p
->right
;
1547 _asn1_check_identifier(node_asn
*node
)
1552 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1556 if(type_field(p
->type
)==TYPE_IDENTIFIER
){
1557 _gnutls_str_cpy(name2
, sizeof(name2
), node
->name
);
1558 _gnutls_str_cat(name2
, sizeof(name2
), ".");
1559 _gnutls_str_cat(name2
, sizeof(name2
), p
->value
);
1560 p2
=_asn1_find_node(node
,name2
);
1561 if(p2
==NULL
){printf("%s\n",name2
); return ASN_IDENTIFIER_NOT_FOUND
;}
1563 else if((type_field(p
->type
)==TYPE_OBJECT_ID
) &&
1564 (p
->type
&CONST_ASSIGN
)){
1566 if(p2
&& (type_field(p2
->type
)==TYPE_CONSTANT
)){
1567 if(p2
->value
&& !isdigit(p2
->value
[0])){
1568 _gnutls_str_cpy(name2
, sizeof(name2
), node
->name
);
1569 _gnutls_str_cat(name2
, sizeof(name2
), ".");
1570 _gnutls_str_cat(name2
, sizeof(name2
), p2
->value
);
1571 p2
=_asn1_find_node(node
,name2
);
1572 if(!p2
|| (type_field(p2
->type
)!=TYPE_OBJECT_ID
) ||
1573 !(p2
->type
&CONST_ASSIGN
))
1574 {printf("%s\n",name2
); return ASN_IDENTIFIER_NOT_FOUND
;}
1582 else if(p
->right
) p
=p
->right
;
1603 _asn1_change_integer_value(node_asn
*node
)
1606 unsigned char val
[4],val2
[5];
1609 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1613 if((type_field(p
->type
)==TYPE_INTEGER
) && (p
->type
&CONST_ASSIGN
)){
1615 _asn1_convert_integer(p
->value
,val
,sizeof(val
), &len
);
1616 _asn1_octet_der(val
,len
,val2
,&len
);
1617 _asn1_set_value(p
,val2
,len
);
1626 else if(p
->right
) p
=p
->right
;
1648 _asn1_delete_not_used(node_asn
*node
)
1652 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1656 if(p
->type
&CONST_NOT_USED
){
1659 p2
=_asn1_find_left(p
);
1660 if(!p2
) p2
=_asn1_find_up(p
);
1662 asn1_delete_structure(p
);
1666 if(!p
) break; /* reach node */
1673 else if(p
->right
) p
=p
->right
;
1695 _asn1_expand_identifier(node_asn
**node
,node_asn
*root
)
1697 node_asn
*p
,*p2
,*p3
;
1701 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1706 while(!((p
==*node
) && (move
==UP
))){
1708 if(type_field(p
->type
)==TYPE_IDENTIFIER
){
1709 _gnutls_str_cpy(name2
, sizeof(name2
), root
->name
);
1710 _gnutls_str_cat(name2
, sizeof(name2
), ".");
1711 _gnutls_str_cat(name2
, sizeof(name2
), p
->value
);
1712 p2
=_asn1_copy_structure2(root
,name2
);
1713 if(p2
==NULL
) return ASN_IDENTIFIER_NOT_FOUND
;
1714 _asn1_set_name(p2
,p
->name
);
1717 if(p
->right
) p
->right
->left
=p2
;
1720 while(p3
->right
) p3
=p3
->right
;
1721 _asn1_set_right(p3
,p2
->down
);
1722 _asn1_set_down(p2
,p
->down
);
1725 p3
=_asn1_find_left(p
);
1726 if(p3
) _asn1_set_right(p3
,p2
);
1728 p3
=_asn1_find_up(p
);
1729 if(p3
) _asn1_set_down(p3
,p2
);
1735 if(p
->type
& CONST_SIZE
) p2
->type
|=CONST_SIZE
;
1736 if(p
->type
& CONST_TAG
) p2
->type
|=CONST_TAG
;
1737 if(p
->type
& CONST_OPTION
) p2
->type
|=CONST_OPTION
;
1738 if(p
->type
& CONST_DEFAULT
) p2
->type
|=CONST_DEFAULT
;
1739 if(p
->type
& CONST_SET
) p2
->type
|=CONST_SET
;
1740 if(p
->type
& CONST_NOT_USED
) p2
->type
|=CONST_NOT_USED
;
1742 if(p
==*node
) *node
=p2
;
1743 _asn1_remove_node(p
);
1753 if(p
->down
) p
=p
->down
;
1757 if(p
==*node
) {move
=UP
; continue;}
1760 if(p
->right
) p
=p
->right
;
1763 if(move
==UP
) p
=_asn1_find_up(p
);
1772 _asn1_type_choice_config(node_asn
*node
)
1774 node_asn
*p
,*p2
,*p3
,*p4
;
1777 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1782 while(!((p
==node
) && (move
==UP
))){
1784 if((type_field(p
->type
)==TYPE_CHOICE
) &&
1785 (p
->type
&CONST_TAG
)){
1788 if(type_field(p2
->type
)!=TYPE_TAG
){
1789 p2
->type
|=CONST_TAG
;
1790 p3
=_asn1_find_left(p2
);
1792 if(type_field(p3
->type
)==TYPE_TAG
){
1793 p4
=_asn1_add_node(p3
->type
);
1794 _asn1_set_value(p4
,p3
->value
,strlen(p3
->value
)+1);
1795 _asn1_set_right(p4
,p2
->down
);
1796 _asn1_set_down(p2
,p4
);
1798 p3
=_asn1_find_left(p3
);
1803 p
->type
&=~(CONST_TAG
);
1807 if(type_field(p2
->type
)==TYPE_TAG
) asn1_delete_structure(p2
);
1816 if(p
->down
) p
=p
->down
;
1820 if(p
==node
) {move
=UP
; continue;}
1823 if(p
->right
) p
=p
->right
;
1826 if(move
==UP
) p
=_asn1_find_up(p
);
1834 _asn1_type_set_config(node_asn
*node
)
1839 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1844 while(!((p
==node
) && (move
==UP
))){
1846 if(type_field(p
->type
)==TYPE_SET
){
1849 if(type_field(p2
->type
)!=TYPE_TAG
)
1850 p2
->type
|=CONST_SET
|CONST_NOT_USED
;
1859 if(p
->down
) p
=p
->down
;
1863 if(p
==node
) {move
=UP
; continue;}
1866 if(p
->right
) p
=p
->right
;
1869 if(move
==UP
) p
=_asn1_find_up(p
);
1877 _asn1_expand_object_id(node_asn
*node
)
1879 node_asn
*p
,*p2
,*p3
,*p4
,*p5
;
1880 char name_root
[129],name2
[129];
1883 if(node
==NULL
) return ASN_ELEMENT_NOT_FOUND
;
1885 _gnutls_str_cpy(name_root
, sizeof(name_root
), node
->name
);
1890 while(!((p
==node
) && (move
==UP
))){
1892 if((type_field(p
->type
)==TYPE_OBJECT_ID
) && (p
->type
&CONST_ASSIGN
)){
1894 if(p2
&& (type_field(p2
->type
)==TYPE_CONSTANT
)){
1895 if(p2
->value
&& !isdigit(p2
->value
[0])){
1896 _gnutls_str_cpy(name2
, sizeof(name2
), name_root
);
1897 _gnutls_str_cat(name2
, sizeof(name2
), ".");
1898 _gnutls_str_cat(name2
, sizeof(name2
), p2
->value
);
1899 p3
=_asn1_find_node(node
,name2
);
1900 if(!p3
|| (type_field(p3
->type
)!=TYPE_OBJECT_ID
) ||
1901 !(p3
->type
&CONST_ASSIGN
)) return ASN_ELEMENT_NOT_FOUND
;
1902 _asn1_set_down(p
,p2
->right
);
1903 _asn1_remove_node(p2
);
1907 if(type_field(p4
->type
)==TYPE_CONSTANT
){
1908 p5
=_asn1_add_node(TYPE_CONSTANT
);
1909 _asn1_set_name(p5
,p4
->name
);
1910 _asn1_set_value(p5
,p4
->value
,strlen(p4
->value
)+1);
1912 _asn1_set_right(p5
,p
->down
);
1913 _asn1_set_down(p
,p5
);
1916 _asn1_set_right(p5
,p2
->right
);
1917 _asn1_set_right(p2
,p5
);
1933 if(p
->down
) p
=p
->down
;
1937 if(p
==node
) {move
=UP
; continue;}
1940 if(p
->right
) p
=p
->right
;
1943 if(move
==UP
) p
=_asn1_find_up(p
);