2 * Copyright (C) 2002 Fabio Fiorina
3 * Copyright (C) 2004 Simon Josefsson
5 * This file is part of LIBASN1.
7 * The LIBTASN1 library is free software; you can redistribute it and/or
8 * 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,
13 * but 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 02110-1301, USA
23 /*****************************************************/
25 /* Description: Functions to create a DER coding of */
27 /*****************************************************/
32 #include "parser_aux.h"
36 #define MAX_TAG_LEN 16
38 /******************************************************/
39 /* Function : _asn1_error_description_value_not_found */
40 /* Description: creates the ErrorDescription string */
41 /* for the ASN1_VALUE_NOT_FOUND error. */
43 /* node: node of the tree where the value is NULL. */
44 /* ErrorDescription: string returned. */
46 /******************************************************/
48 _asn1_error_description_value_not_found(node_asn
*node
,char *ErrorDescription
)
51 if (ErrorDescription
== NULL
) return;
53 Estrcpy(ErrorDescription
,":: value of element '");
54 _asn1_hierarchical_name(node
,ErrorDescription
+strlen(ErrorDescription
),
55 MAX_ERROR_DESCRIPTION_SIZE
-40);
56 Estrcat(ErrorDescription
,"' not found");
60 /******************************************************/
61 /* Function : _asn1_length_der */
62 /* Description: creates the DER coding for the LEN */
63 /* parameter (only the length). */
65 /* len: value to convert. */
66 /* ans: string returned. */
67 /* ans_len: number of meaningful bytes of ANS */
68 /* (ans[0]..ans[ans_len-1]). */
70 /******************************************************/
72 _asn1_length_der(unsigned long len
,unsigned char *ans
,int *ans_len
)
75 unsigned char temp
[SIZEOF_UNSIGNED_LONG_INT
];
79 if(ans
!=NULL
) ans
[0]=(unsigned char)len
;
91 ans
[0]=((unsigned char)k
&0x7F)+128;
92 while(k
--) ans
[*ans_len
-1-k
]=temp
[k
];
97 /******************************************************/
98 /* Function : _asn1_tag_der */
99 /* Description: creates the DER coding for the CLASS */
100 /* and TAG parameters. */
102 /* class: value to convert. */
103 /* tag_value: value to convert. */
104 /* ans: string returned. */
105 /* ans_len: number of meaningful bytes of ANS */
106 /* (ans[0]..ans[ans_len-1]). */
108 /******************************************************/
110 _asn1_tag_der(unsigned char class,unsigned int tag_value
,unsigned char *ans
,int *ans_len
)
113 unsigned char temp
[SIZEOF_UNSIGNED_INT
];
117 ans
[0]=(class&0xE0) + ((unsigned char)(tag_value
&0x1F));
122 ans
[0]=(class&0xE0) + 31;
125 temp
[k
++]=tag_value
&0x7F;
126 tag_value
=tag_value
>>7;
129 while(k
--) ans
[*ans_len
-1-k
]=temp
[k
]+128;
130 ans
[*ans_len
-1]-=128;
134 /******************************************************/
135 /* Function : _asn1_octect_der */
136 /* Description: creates the DER coding for an */
137 /* OCTET type (length included). */
139 /* str: OCTET string. */
140 /* str_len: STR length (str[0]..str[str_len-1]). */
141 /* der: string returned. */
142 /* der_len: number of meaningful bytes of DER */
143 /* (der[0]..der[ans_len-1]). */
145 /******************************************************/
147 _asn1_octet_der(const unsigned char *str
,int str_len
,unsigned char *der
,int *der_len
)
151 if(der
==NULL
) return;
152 _asn1_length_der(str_len
,der
,&len_len
);
153 memcpy(der
+len_len
,str
,str_len
);
154 *der_len
=str_len
+len_len
;
157 /******************************************************/
158 /* Function : _asn1_time_der */
159 /* Description: creates the DER coding for a TIME */
160 /* type (length included). */
162 /* str: TIME null-terminated string. */
163 /* der: string returned. */
164 /* der_len: number of meaningful bytes of DER */
165 /* (der[0]..der[ans_len-1]). Initially it */
166 /* if must store the lenght of DER. */
168 /* ASN1_MEM_ERROR when DER isn't big enough */
169 /* ASN1_SUCCESS otherwise */
170 /******************************************************/
172 _asn1_time_der(unsigned char *str
,unsigned char *der
,int *der_len
)
179 _asn1_length_der(strlen(str
),(max_len
>0)?der
:NULL
,&len_len
);
181 if((len_len
+(int)strlen(str
))<=max_len
)
182 memcpy(der
+len_len
,str
,strlen(str
));
183 *der_len
=len_len
+strlen(str
);
185 if((*der_len
)>max_len
) return ASN1_MEM_ERROR
;
193 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
198 if(str==NULL) return;
199 str_len=_asn1_get_length_der(der,&len_len);
200 memcpy(temp,der+len_len,str_len);
201 *der_len=str_len+len_len;
205 strcat(temp,"00+0000");
209 strcat(temp,"+0000");
213 memmove(temp+12,temp+10,6);
214 temp[10]=temp[11]='0';
226 /******************************************************/
227 /* Function : _asn1_objectid_der */
228 /* Description: creates the DER coding for an */
229 /* OBJECT IDENTIFIER type (length included). */
231 /* str: OBJECT IDENTIFIER null-terminated string. */
232 /* der: string returned. */
233 /* der_len: number of meaningful bytes of DER */
234 /* (der[0]..der[ans_len-1]). Initially it */
235 /* must store the length of DER. */
237 /* ASN1_MEM_ERROR when DER isn't big enough */
238 /* ASN1_SUCCESS otherwise */
239 /******************************************************/
241 _asn1_objectid_der(unsigned char *str
,unsigned char *der
,int *der_len
)
243 int len_len
,counter
,k
,first
,max_len
;
244 char *temp
,*n_end
,*n_start
;
246 unsigned long val
,val1
=0;
250 temp
= (char *) _asn1_alloca(strlen(str
)+2);
251 if(temp
==NULL
) return ASN1_MEM_ALLOC_ERROR
;
258 while((n_end
=strchr(n_start
,'.'))){
260 val
=strtoul(n_start
,NULL
,10);
263 if(counter
==1) val1
=val
;
272 bit7
=(val
>>(k
*7))&0x7F;
273 if(bit7
|| first
|| !k
){
275 if(max_len
>(*der_len
))
286 _asn1_length_der(*der_len
,NULL
,&len_len
);
287 if(max_len
>=(*der_len
+len_len
)){
288 memmove(der
+len_len
,der
,*der_len
);
289 _asn1_length_der(*der_len
,der
,&len_len
);
295 if(max_len
<(*der_len
)) return ASN1_MEM_ERROR
;
301 char bit_mask
[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
303 /******************************************************/
304 /* Function : _asn1_bit_der */
305 /* Description: creates the DER coding for a BIT */
306 /* STRING type (length and pad included). */
308 /* str: BIT string. */
309 /* bit_len: number of meaningful bits in STR. */
310 /* der: string returned. */
311 /* der_len: number of meaningful bytes of DER */
312 /* (der[0]..der[ans_len-1]). */
314 /******************************************************/
316 _asn1_bit_der(const unsigned char *str
,int bit_len
,unsigned char *der
,int *der_len
)
318 int len_len
,len_byte
,len_pad
;
320 if(der
==NULL
) return;
322 len_pad
=8-(bit_len
&7);
323 if(len_pad
==8) len_pad
=0;
325 _asn1_length_der(len_byte
+1,der
,&len_len
);
326 der
[len_len
]=len_pad
;
327 memcpy(der
+len_len
+1,str
,len_byte
);
328 der
[len_len
+len_byte
]&=bit_mask
[len_pad
];
329 *der_len
=len_byte
+len_len
+1;
333 /******************************************************/
334 /* Function : _asn1_complete_explicit_tag */
335 /* Description: add the length coding to the EXPLICIT */
338 /* node: pointer to the tree element. */
339 /* der: string with the DER coding of the whole tree*/
340 /* counter: number of meaningful bytes of DER */
341 /* (der[0]..der[*counter-1]). */
342 /* max_len: size of der vector */
344 /* ASN1_MEM_ERROR if der vector isn't big enough, */
345 /* otherwise ASN1_SUCCESS. */
346 /******************************************************/
348 _asn1_complete_explicit_tag(node_asn
*node
,unsigned char *der
,int *counter
,int *max_len
)
351 int is_tag_implicit
,len2
,len3
;
352 unsigned char temp
[SIZEOF_UNSIGNED_INT
];
356 if(node
->type
&CONST_TAG
){
358 /* When there are nested tags we must complete them reverse to
359 the order they were created. This is because completing a tag
360 modifies all data within it, including the incomplete tags
361 which store buffer positions -- simon@josefsson.org 2002-09-06
365 while(p
&& p
!=node
->down
->left
){
366 if(type_field(p
->type
)==TYPE_TAG
){
367 if(p
->type
&CONST_EXPLICIT
){
368 len2
=strtol(p
->name
,NULL
,10);
369 _asn1_set_name(p
,NULL
);
370 _asn1_length_der(*counter
-len2
,temp
,&len3
);
371 if(len3
<=(*max_len
)){
372 memmove(der
+len2
+len3
,der
+len2
,*counter
-len2
);
373 memcpy(der
+len2
,temp
,len3
);
379 else{ /* CONST_IMPLICIT */
380 if(!is_tag_implicit
){
389 if(*max_len
<0) return ASN1_MEM_ERROR
;
395 /******************************************************/
396 /* Function : _asn1_insert_tag_der */
397 /* Description: creates the DER coding of tags of one */
400 /* node: pointer to the tree element. */
401 /* der: string returned */
402 /* counter: number of meaningful bytes of DER */
403 /* (counter[0]..der[*counter-1]). */
404 /* max_len: size of der vector */
406 /* ASN1_GENERIC_ERROR if the type is unknown, */
407 /* ASN1_MEM_ERROR if der vector isn't big enough, */
408 /* otherwise ASN1_SUCCESS. */
409 /******************************************************/
411 _asn1_insert_tag_der(node_asn
*node
,unsigned char *der
,int *counter
,int *max_len
)
414 int tag_len
,is_tag_implicit
;
415 unsigned char class,class_implicit
=0,temp
[SIZEOF_UNSIGNED_INT
*3+1];
416 unsigned long tag_implicit
=0;
417 char tag_der
[MAX_TAG_LEN
];
421 if(node
->type
&CONST_TAG
){
424 if(type_field(p
->type
)==TYPE_TAG
){
425 if(p
->type
&CONST_APPLICATION
) class=APPLICATION
;
426 else if(p
->type
&CONST_UNIVERSAL
) class=UNIVERSAL
;
427 else if(p
->type
&CONST_PRIVATE
) class=PRIVATE
;
428 else class=CONTEXT_SPECIFIC
;
430 if(p
->type
&CONST_EXPLICIT
){
432 _asn1_tag_der(class_implicit
,tag_implicit
,tag_der
,&tag_len
);
434 _asn1_tag_der(class|STRUCTURED
,strtoul(p
->value
,NULL
,10),tag_der
,&tag_len
);
438 memcpy(der
+*counter
,tag_der
,tag_len
);
441 _asn1_ltostr(*counter
,temp
);
442 _asn1_set_name(p
,temp
);
446 else{ /* CONST_IMPLICIT */
447 if(!is_tag_implicit
){
448 if((type_field(node
->type
)==TYPE_SEQUENCE
) ||
449 (type_field(node
->type
)==TYPE_SEQUENCE_OF
) ||
450 (type_field(node
->type
)==TYPE_SET
) ||
451 (type_field(node
->type
)==TYPE_SET_OF
)) class|=STRUCTURED
;
452 class_implicit
=class;
453 tag_implicit
=strtoul(p
->value
,NULL
,10);
463 _asn1_tag_der(class_implicit
,tag_implicit
,tag_der
,&tag_len
);
466 switch(type_field(node
->type
)){
468 _asn1_tag_der(UNIVERSAL
,TAG_NULL
,tag_der
,&tag_len
);
471 _asn1_tag_der(UNIVERSAL
,TAG_BOOLEAN
,tag_der
,&tag_len
);
474 _asn1_tag_der(UNIVERSAL
,TAG_INTEGER
,tag_der
,&tag_len
);
476 case TYPE_ENUMERATED
:
477 _asn1_tag_der(UNIVERSAL
,TAG_ENUMERATED
,tag_der
,&tag_len
);
480 _asn1_tag_der(UNIVERSAL
,TAG_OBJECT_ID
,tag_der
,&tag_len
);
483 if(node
->type
&CONST_UTC
){
484 _asn1_tag_der(UNIVERSAL
,TAG_UTCTime
,tag_der
,&tag_len
);
486 else _asn1_tag_der(UNIVERSAL
,TAG_GENERALIZEDTime
,tag_der
,&tag_len
);
488 case TYPE_OCTET_STRING
:
489 _asn1_tag_der(UNIVERSAL
,TAG_OCTET_STRING
,tag_der
,&tag_len
);
491 case TYPE_GENERALSTRING
:
492 _asn1_tag_der(UNIVERSAL
,TAG_GENERALSTRING
,tag_der
,&tag_len
);
494 case TYPE_BIT_STRING
:
495 _asn1_tag_der(UNIVERSAL
,TAG_BIT_STRING
,tag_der
,&tag_len
);
497 case TYPE_SEQUENCE
: case TYPE_SEQUENCE_OF
:
498 _asn1_tag_der(UNIVERSAL
|STRUCTURED
,TAG_SEQUENCE
,tag_der
,&tag_len
);
500 case TYPE_SET
: case TYPE_SET_OF
:
501 _asn1_tag_der(UNIVERSAL
|STRUCTURED
,TAG_SET
,tag_der
,&tag_len
);
513 return ASN1_GENERIC_ERROR
;
519 memcpy(der
+*counter
,tag_der
,tag_len
);
522 if(*max_len
<0) return ASN1_MEM_ERROR
;
527 /******************************************************/
528 /* Function : _asn1_ordering_set */
529 /* Description: puts the elements of a SET type in */
530 /* the correct order according to DER rules. */
532 /* der: string with the DER coding. */
533 /* node: pointer to the SET element. */
535 /******************************************************/
537 _asn1_ordering_set(unsigned char *der
,node_asn
*node
)
542 struct vet
*next
,*prev
;
545 int counter
,len
,len2
;
546 struct vet
*first
,*last
,*p_vet
,*p2_vet
;
548 unsigned char class,*temp
;
553 if(type_field(node
->type
)!=TYPE_SET
) return;
556 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
558 if((p
==NULL
) || (p
->right
==NULL
)) return;
562 p_vet
=(struct vet
*)_asn1_alloca( sizeof(struct vet
));
563 if (p_vet
==NULL
) return;
567 if(first
==NULL
) first
=p_vet
;
568 else last
->next
=p_vet
;
571 /* tag value calculation */
572 tag
=_asn1_get_tag_der(der
+counter
,&class,&len2
);
573 p_vet
->value
=(class<<24)|tag
;
576 /* extraction and length */
577 len2
=_asn1_get_length_der(der
+counter
,&len
);
590 if(p_vet
->value
>p2_vet
->value
){
591 /* change position */
592 temp
=(unsigned char *)_asn1_alloca( p_vet
->end
-counter
);
593 if (temp
==NULL
) return;
595 memcpy(temp
,der
+counter
,p_vet
->end
-counter
);
596 memcpy(der
+counter
,der
+p_vet
->end
,p2_vet
->end
-p_vet
->end
);
597 memcpy(der
+counter
+p2_vet
->end
-p_vet
->end
,temp
,p_vet
->end
-counter
);
601 p_vet
->value
=p2_vet
->value
;
604 p_vet
->end
=counter
+(p2_vet
->end
-p_vet
->end
);
612 if(p_vet
!=first
) p_vet
->prev
->next
=NULL
;
619 /******************************************************/
620 /* Function : _asn1_ordering_set_of */
621 /* Description: puts the elements of a SET OF type in */
622 /* the correct order according to DER rules. */
624 /* der: string with the DER coding. */
625 /* node: pointer to the SET OF element. */
627 /******************************************************/
629 _asn1_ordering_set_of(unsigned char *der
,node_asn
*node
)
633 struct vet
*next
,*prev
;
636 int counter
,len
,len2
,change
;
637 struct vet
*first
,*last
,*p_vet
,*p2_vet
;
639 unsigned char *temp
,class;
644 if(type_field(node
->type
)!=TYPE_SET_OF
) return;
647 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
650 if((p
==NULL
) || (p
->right
==NULL
)) return;
654 p_vet
=(struct vet
*)_asn1_alloca(sizeof(struct vet
));
655 if (p_vet
==NULL
) return;
659 if(first
==NULL
) first
=p_vet
;
660 else last
->next
=p_vet
;
663 /* extraction of tag and length */
664 _asn1_get_tag_der(der
+counter
,&class,&len
);
666 len2
=_asn1_get_length_der(der
+counter
,&len
);
679 if((p_vet
->end
-counter
)>(p2_vet
->end
-p_vet
->end
))
680 max
=p_vet
->end
-counter
;
682 max
=p2_vet
->end
-p_vet
->end
;
686 if(der
[counter
+k
]>der
[p_vet
->end
+k
]){change
=1;break;}
687 else if(der
[counter
+k
]<der
[p_vet
->end
+k
]){change
=0;break;}
689 if((change
==-1) && ((p_vet
->end
-counter
)>(p2_vet
->end
-p_vet
->end
)))
693 /* change position */
694 temp
=(unsigned char *)_asn1_alloca(p_vet
->end
-counter
);
695 if (temp
==NULL
) return;
697 memcpy(temp
,der
+counter
,(p_vet
->end
)-counter
);
698 memcpy(der
+counter
,der
+(p_vet
->end
),(p2_vet
->end
)-(p_vet
->end
));
699 memcpy(der
+counter
+(p2_vet
->end
)-(p_vet
->end
),temp
,(p_vet
->end
)-counter
);
702 p_vet
->end
=counter
+(p2_vet
->end
-p_vet
->end
);
710 if(p_vet
!=first
) p_vet
->prev
->next
=NULL
;
718 * asn1_der_coding - Creates the DER encoding for the NAME structure
719 * @element: pointer to an ASN1 element
720 * @name: the name of the structure you want to encode (it must be
722 * @ider: vector that will contain the DER encoding. DER must be a
723 * pointer to memory cells already allocated.
724 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
725 * holds the sizeof of der vector.
726 * @errorDescription : return the error description or an empty
729 * Creates the DER encoding for the NAME structure (inside *POINTER
734 * ASN1_SUCCESS: DER encoding OK.
736 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
738 * ASN1_VALUE_NOT_FOUND: There is an element without a value.
740 * ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
741 * LEN will contain the length needed.
745 asn1_der_coding(ASN1_TYPE element
,const char *name
,void *ider
,int *len
,
746 char *ErrorDescription
)
748 node_asn
*node
,*p
,*p2
;
749 char temp
[SIZEOF_UNSIGNED_LONG_INT
*3+1];
750 int counter
,counter_old
,len2
,len3
,tlen
,move
,max_len
,max_len_old
;
752 unsigned char* der
= ider
;
754 node
=_asn1_find_node(element
,name
);
755 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
767 ris
=_asn1_insert_tag_der(p
,der
,&counter
,&max_len
);
769 switch(type_field(p
->type
)){
777 if((p
->type
&CONST_DEFAULT
) && (p
->value
==NULL
)){
783 _asn1_error_description_value_not_found(p
,ErrorDescription
);
784 return ASN1_VALUE_NOT_FOUND
;
789 if(p
->value
[0]=='F') der
[counter
++]=0;
790 else der
[counter
++]=0xFF;
797 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
798 if((p
->type
&CONST_DEFAULT
) && (p
->value
==NULL
)){
804 _asn1_error_description_value_not_found(p
,ErrorDescription
);
805 return ASN1_VALUE_NOT_FOUND
;
807 len2
=_asn1_get_length_der(p
->value
,&len3
);
808 max_len
-= len2
+len3
;
810 memcpy(der
+counter
,p
->value
,len3
+len2
);
816 if((p
->type
&CONST_DEFAULT
) && (p
->value
==NULL
)){
822 _asn1_error_description_value_not_found(p
,ErrorDescription
);
823 return ASN1_VALUE_NOT_FOUND
;
826 ris
=_asn1_objectid_der(p
->value
,der
+counter
,&len2
);
827 if(ris
==ASN1_MEM_ALLOC_ERROR
) return ris
;
835 _asn1_error_description_value_not_found(p
,ErrorDescription
);
836 return ASN1_VALUE_NOT_FOUND
;
839 ris
=_asn1_time_der(p
->value
,der
+counter
,&len2
);
844 case TYPE_OCTET_STRING
:
846 _asn1_error_description_value_not_found(p
,ErrorDescription
);
847 return ASN1_VALUE_NOT_FOUND
;
849 len2
=_asn1_get_length_der(p
->value
,&len3
);
852 memcpy(der
+counter
,p
->value
,len3
+len2
);
856 case TYPE_GENERALSTRING
:
858 _asn1_error_description_value_not_found(p
,ErrorDescription
);
859 return ASN1_VALUE_NOT_FOUND
;
861 len2
=_asn1_get_length_der(p
->value
,&len3
);
864 memcpy(der
+counter
,p
->value
,len3
+len2
);
868 case TYPE_BIT_STRING
:
870 _asn1_error_description_value_not_found(p
,ErrorDescription
);
871 return ASN1_VALUE_NOT_FOUND
;
873 len2
=_asn1_get_length_der(p
->value
,&len3
);
876 memcpy(der
+counter
,p
->value
,len3
+len2
);
880 case TYPE_SEQUENCE
: case TYPE_SET
:
882 _asn1_ltostr(counter
,temp
);
885 _asn1_set_value(p
,temp
,tlen
+1);
892 while(p2
&& (type_field(p2
->type
)==TYPE_TAG
)) p2
=p2
->right
;
903 len2
=strtol(p
->value
,NULL
,10);
904 _asn1_set_value(p
,NULL
,0);
905 if((type_field(p
->type
)==TYPE_SET
) && (max_len
>=0))
906 _asn1_ordering_set(der
+len2
,p
);
907 _asn1_length_der(counter
-len2
,temp
,&len3
);
910 memmove(der
+len2
+len3
,der
+len2
,counter
-len2
);
911 memcpy(der
+len2
,temp
,len3
);
917 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
919 _asn1_ltostr(counter
,temp
);
923 _asn1_set_value(p
,temp
,tlen
+1);
925 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
931 else p
=_asn1_find_up(p
);
935 len2
=strtol(p
->value
,NULL
,10);
936 _asn1_set_value(p
,NULL
,0);
937 if((type_field(p
->type
)==TYPE_SET_OF
) && (max_len
>=0))
938 _asn1_ordering_set_of(der
+len2
,p
);
939 _asn1_length_der(counter
-len2
,temp
,&len3
);
942 memmove(der
+len2
+len3
,der
+len2
,counter
-len2
);
943 memcpy(der
+len2
,temp
,len3
);
951 _asn1_error_description_value_not_found(p
,ErrorDescription
);
952 return ASN1_VALUE_NOT_FOUND
;
954 len2
=_asn1_get_length_der(p
->value
,&len3
);
957 memcpy(der
+counter
,p
->value
+len3
,len2
);
962 move
=(move
==UP
)?RIGHT
:DOWN
;
966 if((move
!=DOWN
) && (counter
!=counter_old
)){
967 ris
=_asn1_complete_explicit_tag(p
,der
,&counter
,&max_len
);
970 if(p
==node
&& move
!=DOWN
) break;
973 if(p
->down
) p
=p
->down
;
977 if(p
->right
) p
=p
->right
;
980 if(move
==UP
) p
=_asn1_find_up(p
);
985 if(max_len
<0) return ASN1_MEM_ERROR
;