add vector length check
[libtasn1.git] / lib / coding.c
blobea211410a3d6f235e674b516ba76e64a356b6c63
1 /*
2 * Copyright (C) 2002 Fabio Fiorina
4 * This file is part of LIBASN1.
6 * The LIBTASN1 library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /*****************************************************/
23 /* File: coding.c */
24 /* Description: Functions to create a DER coding of */
25 /* an ASN1 type. */
26 /*****************************************************/
28 #include <int.h>
29 #include <errors.h>
30 #include "der.h"
31 #include "parser_aux.h"
32 #include <gstr.h>
33 #include "element.h"
35 #define MAX_TAG_LEN 16
37 /******************************************************/
38 /* Function : _asn1_error_description_value_not_found */
39 /* Description: creates the ErrorDescription string */
40 /* for the ASN1_VALUE_NOT_FOUND error. */
41 /* Parameters: */
42 /* node: node of the tree where the value is NULL. */
43 /* ErrorDescription: string returned. */
44 /* Return: */
45 /******************************************************/
46 void
47 _asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription)
50 if (ErrorDescription == NULL) return;
52 Estrcpy(ErrorDescription,":: value of element '");
53 _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
54 MAX_ERROR_DESCRIPTION_SIZE-40);
55 Estrcat(ErrorDescription,"' not found");
59 /******************************************************/
60 /* Function : _asn1_length_der */
61 /* Description: creates the DER coding for the LEN */
62 /* parameter (only the length). */
63 /* Parameters: */
64 /* len: value to convert. */
65 /* ans: string returned. */
66 /* ans_len: number of meanful bytes of ANS */
67 /* (ans[0]..ans[ans_len-1]). */
68 /* Return: */
69 /******************************************************/
70 void
71 _asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len)
73 int k;
74 unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
76 if(len<128){
77 /* short form */
78 if(ans!=NULL) ans[0]=(unsigned char)len;
79 *ans_len=1;
81 else{
82 /* Long form */
83 k=0;
84 while(len){
85 temp[k++]=len&0xFF;
86 len=len>>8;
88 *ans_len=k+1;
89 if(ans!=NULL){
90 ans[0]=((unsigned char)k&0x7F)+128;
91 while(k--) ans[*ans_len-1-k]=temp[k];
96 /******************************************************/
97 /* Function : _asn1_tag_der */
98 /* Description: creates the DER coding for the CLASS */
99 /* and TAG parameters. */
100 /* Parameters: */
101 /* class: value to convert. */
102 /* tag_value: value to convert. */
103 /* ans: string returned. */
104 /* ans_len: number of meanful bytes of ANS */
105 /* (ans[0]..ans[ans_len-1]). */
106 /* Return: */
107 /******************************************************/
108 void
109 _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int *ans_len)
111 int k;
112 unsigned char temp[SIZEOF_UNSIGNED_INT];
114 if(tag_value<30){
115 /* short form */
116 ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F));
117 *ans_len=1;
119 else{
120 /* Long form */
121 ans[0]=(class&0xE0) + 31;
122 k=0;
123 while(tag_value){
124 temp[k++]=tag_value&0x7F;
125 tag_value=tag_value>>7;
127 *ans_len=k+1;
128 while(k--) ans[*ans_len-1-k]=temp[k]+128;
129 ans[*ans_len-1]-=128;
133 /******************************************************/
134 /* Function : _asn1_octect_der */
135 /* Description: creates the DER coding for an */
136 /* OCTET type (length included). */
137 /* Parameters: */
138 /* str: OCTET string. */
139 /* str_len: STR length (str[0]..str[str_len-1]). */
140 /* der: string returned. */
141 /* der_len: number of meanful bytes of DER */
142 /* (der[0]..der[ans_len-1]). */
143 /* Return: */
144 /******************************************************/
145 void
146 _asn1_octet_der(const unsigned char *str,int str_len,unsigned char *der,int *der_len)
148 int len_len;
150 if(der==NULL) return;
151 _asn1_length_der(str_len,der,&len_len);
152 memcpy(der+len_len,str,str_len);
153 *der_len=str_len+len_len;
156 /******************************************************/
157 /* Function : _asn1_time_der */
158 /* Description: creates the DER coding for a TIME */
159 /* type (length included). */
160 /* Parameters: */
161 /* str: TIME null-terminated string. */
162 /* der: string returned. */
163 /* der_len: number of meanful bytes of DER */
164 /* (der[0]..der[ans_len-1]). Initially it */
165 /* if must store the lenght of DER. */
166 /* Return: */
167 /* ASN1_MEM_ERROR when DER isn't big enough */
168 /* ASN1_SUCCESS otherwise */
169 /******************************************************/
170 asn1_retCode
171 _asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
173 int len_len;
174 int max_len;
176 max_len=*der_len;
178 if(der==NULL) return ASN1_SUCCESS;
179 _asn1_length_der(strlen(str),der,&len_len);
180 if((len_len+strlen(str))<=max_len)
181 memcpy(der+len_len,str,strlen(str));
182 *der_len=len_len+strlen(str);
184 if((*der_len)>max_len) return ASN1_MEM_ERROR;
186 return ASN1_SUCCESS;
191 void
192 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
194 int len_len,str_len;
195 char temp[20];
197 if(str==NULL) return;
198 str_len=_asn1_get_length_der(der,&len_len);
199 memcpy(temp,der+len_len,str_len);
200 *der_len=str_len+len_len;
201 switch(str_len){
202 case 11:
203 temp[10]=0;
204 strcat(temp,"00+0000");
205 break;
206 case 13:
207 temp[12]=0;
208 strcat(temp,"+0000");
209 break;
210 case 15:
211 temp[15]=0;
212 memmove(temp+12,temp+10,6);
213 temp[10]=temp[11]='0';
214 break;
215 case 17:
216 temp[17]=0;
217 break;
218 default:
219 return;
221 strcpy(str,temp);
225 /******************************************************/
226 /* Function : _asn1_objectid_der */
227 /* Description: creates the DER coding for an */
228 /* OBJECT IDENTIFIER type (length included). */
229 /* Parameters: */
230 /* str: OBJECT IDENTIFIER null-terminated string. */
231 /* der: string returned. */
232 /* der_len: number of meanful bytes of DER */
233 /* (der[0]..der[ans_len-1]). Initially it */
234 /* if must store the lenght of DER. */
235 /* Return: */
236 /* ASN1_MEM_ERROR when DER isn't big enough */
237 /* ASN1_SUCCESS otherwise */
238 /******************************************************/
239 asn1_retCode
240 _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
242 int len_len,counter,k,first,max_len;
243 char *temp,*n_end,*n_start;
244 unsigned char bit7;
245 unsigned long val,val1=0;
247 if(der==NULL) return ASN1_SUCCESS;
249 max_len=*der_len;
251 temp=(char *) malloc(strlen(str)+2);
253 strcpy(temp, str);
254 strcat(temp, ".");
256 counter=0;
257 n_start=temp;
258 while((n_end=strchr(n_start,'.'))){
259 *n_end=0;
260 val=strtoul(n_start,NULL,10);
261 counter++;
263 if(counter==1) val1=val;
264 else if(counter==2){
265 if(max_len>0)
266 der[0]=40*val1+val;
267 *der_len=1;
269 else{
270 first=0;
271 for(k=4;k>=0;k--){
272 bit7=(val>>(k*7))&0x7F;
273 if(bit7 || first || !k){
274 if(k) bit7|=0x80;
275 if(max_len>(*der_len))
276 der[*der_len]=bit7;
277 (*der_len)++;
278 first=1;
283 n_start=n_end+1;
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);
291 *der_len+=len_len;
293 free(temp);
295 if(max_len<(*der_len)) return ASN1_MEM_ERROR;
297 return ASN1_SUCCESS;
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). */
307 /* Parameters: */
308 /* str: BIT string. */
309 /* bit_len: number of meanful bits in STR. */
310 /* der: string returned. */
311 /* der_len: number of meanful bytes of DER */
312 /* (der[0]..der[ans_len-1]). */
313 /* Return: */
314 /******************************************************/
315 void
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;
321 len_byte=bit_len>>3;
322 len_pad=8-(bit_len&7);
323 if(len_pad==8) len_pad=0;
324 else len_byte++;
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 */
336 /* tags. */
337 /* Parameters: */
338 /* node: pointer to the tree element. */
339 /* der: string with the DER coding of the whole tree*/
340 /* counter: number of meanful bytes of DER */
341 /* (der[0]..der[*counter-1]). */
342 /* max_len: size of der vector */
343 /* Return: */
344 /* ASN1_MEM_ERROR if der vector isn't big enough, */
345 /* otherwise ASN1_SUCCESS. */
346 /******************************************************/
347 asn1_retCode
348 _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len)
350 node_asn *p;
351 int is_tag_implicit,len2,len3;
352 unsigned char temp[SIZEOF_UNSIGNED_INT];
354 is_tag_implicit=0;
356 if(node->type&CONST_TAG){
357 p=node->down;
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 alla date within it, including the incomplete tags
361 which store buffer positions -- simon@josefsson.org 2002-09-06
363 while(p->right)
364 p=p->right;
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);
375 *max_len -= len3;
376 *counter+=len3;
377 is_tag_implicit=0;
379 else{ /* CONST_IMPLICIT */
380 if(!is_tag_implicit){
381 is_tag_implicit=1;
385 p=p->left;
389 if(*max_len<0) return ASN1_MEM_ERROR;
391 return ASN1_SUCCESS;
395 /******************************************************/
396 /* Function : _asn1_insert_tag_der */
397 /* Description: creates the DER coding of tags of one */
398 /* NODE. */
399 /* Parameters: */
400 /* node: pointer to the tree element. */
401 /* der: string returned */
402 /* counter: number of meanful bytes of DER */
403 /* (counter[0]..der[*counter-1]). */
404 /* max_len: size of der vector */
405 /* Return: */
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 /******************************************************/
410 asn1_retCode
411 _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len)
413 node_asn *p;
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];
419 is_tag_implicit=0;
421 if(node->type&CONST_TAG){
422 p=node->down;
423 while(p){
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){
431 if(is_tag_implicit)
432 _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
433 else
434 _asn1_tag_der(class|STRUCTURED,strtoul(p->value,NULL,10),tag_der,&tag_len);
436 *max_len -= tag_len;
437 if(*max_len>=0)
438 memcpy(der+*counter,tag_der,tag_len);
439 *counter+=tag_len;
441 _asn1_ltostr(*counter,temp);
442 _asn1_set_name(p,temp);
444 is_tag_implicit=0;
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);
454 is_tag_implicit=1;
458 p=p->right;
462 if(is_tag_implicit){
463 _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
465 else{
466 switch(type_field(node->type)){
467 case TYPE_NULL:
468 _asn1_tag_der(UNIVERSAL,TAG_NULL,tag_der,&tag_len);
469 break;
470 case TYPE_BOOLEAN:
471 _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,tag_der,&tag_len);
472 break;
473 case TYPE_INTEGER:
474 _asn1_tag_der(UNIVERSAL,TAG_INTEGER,tag_der,&tag_len);
475 break;
476 case TYPE_ENUMERATED:
477 _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,tag_der,&tag_len);
478 break;
479 case TYPE_OBJECT_ID:
480 _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,tag_der,&tag_len);
481 break;
482 case TYPE_TIME:
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);
487 break;
488 case TYPE_OCTET_STRING:
489 _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,tag_der,&tag_len);
490 break;
491 case TYPE_GENERALSTRING:
492 _asn1_tag_der(UNIVERSAL,TAG_GENERALSTRING,tag_der,&tag_len);
493 break;
494 case TYPE_BIT_STRING:
495 _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,tag_der,&tag_len);
496 break;
497 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
498 _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,tag_der,&tag_len);
499 break;
500 case TYPE_SET: case TYPE_SET_OF:
501 _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,tag_der,&tag_len);
502 break;
503 case TYPE_TAG:
504 tag_len=0;
505 break;
506 case TYPE_CHOICE:
507 tag_len=0;
508 break;
509 case TYPE_ANY:
510 tag_len=0;
511 break;
512 default:
513 return ASN1_GENERIC_ERROR;
517 *max_len -= tag_len;
518 if(*max_len>=0)
519 memcpy(der+*counter,tag_der,tag_len);
520 *counter+=tag_len;
522 if(*max_len<0) return ASN1_MEM_ERROR;
524 return ASN1_SUCCESS;
527 /******************************************************/
528 /* Function : _asn1_ordering_set */
529 /* Description: puts the elements of a SET type in */
530 /* the correct order according to DER rules. */
531 /* Parameters: */
532 /* der: string with the DER coding. */
533 /* node: pointer to the SET element. */
534 /* Return: */
535 /******************************************************/
536 void
537 _asn1_ordering_set(unsigned char *der,node_asn *node)
539 struct vet{
540 int end;
541 unsigned long value;
542 struct vet *next,*prev;
545 int counter,len,len2;
546 struct vet *first,*last,*p_vet,*p2_vet;
547 node_asn *p;
548 unsigned char class,*temp;
549 unsigned long tag;
551 counter=0;
553 if(type_field(node->type)!=TYPE_SET) return;
555 p=node->down;
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;
560 first=last=NULL;
561 while(p){
562 p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
563 if (p_vet==NULL) return;
565 p_vet->next=NULL;
566 p_vet->prev=last;
567 if(first==NULL) first=p_vet;
568 else last->next=p_vet;
569 last=p_vet;
571 /* tag value calculation */
572 tag=_asn1_get_tag_der(der+counter,&class,&len2);
573 p_vet->value=(class<<24)|tag;
574 counter+=len2;
576 /* extraction and length */
577 len2=_asn1_get_length_der(der+counter,&len);
578 counter+=len+len2;
580 p_vet->end=counter;
581 p=p->right;
584 p_vet=first;
586 while(p_vet){
587 p2_vet=p_vet->next;
588 counter=0;
589 while(p2_vet){
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 memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
597 memcpy(der+p_vet->end,temp,p_vet->end-counter);
598 _asn1_afree(temp);
600 tag=p_vet->value;
601 p_vet->value=p2_vet->value;
602 p2_vet->value=tag;
604 p_vet->end=counter+(p2_vet->end-p_vet->end);
606 counter=p_vet->end;
608 p2_vet=p2_vet->next;
609 p_vet=p_vet->next;
612 if(p_vet!=first) p_vet->prev->next=NULL;
613 else first=NULL;
614 _asn1_afree(p_vet);
615 p_vet=first;
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. */
623 /* Parameters: */
624 /* der: string with the DER coding. */
625 /* node: pointer to the SET OF element. */
626 /* Return: */
627 /******************************************************/
628 void
629 _asn1_ordering_set_of(unsigned char *der,node_asn *node)
631 struct vet{
632 int end;
633 struct vet *next,*prev;
636 int counter,len,len2,change;
637 struct vet *first,*last,*p_vet,*p2_vet;
638 node_asn *p;
639 unsigned char *temp,class;
640 unsigned long k,max;
642 counter=0;
644 if(type_field(node->type)!=TYPE_SET_OF) return;
646 p=node->down;
647 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
648 p=p->right;
650 if((p==NULL) || (p->right==NULL)) return;
652 first=last=NULL;
653 while(p){
654 p_vet=(struct vet *)_asn1_alloca(sizeof(struct vet));
655 if (p_vet==NULL) return;
657 p_vet->next=NULL;
658 p_vet->prev=last;
659 if(first==NULL) first=p_vet;
660 else last->next=p_vet;
661 last=p_vet;
663 /* extraction of tag and length */
664 _asn1_get_tag_der(der+counter,&class,&len);
665 counter+=len;
666 len2=_asn1_get_length_der(der+counter,&len);
667 counter+=len+len2;
669 p_vet->end=counter;
670 p=p->right;
673 p_vet=first;
675 while(p_vet){
676 p2_vet=p_vet->next;
677 counter=0;
678 while(p2_vet){
679 if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
680 max=p_vet->end-counter;
681 else
682 max=p2_vet->end-p_vet->end;
684 change=-1;
685 for(k=0;k<max;k++)
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)))
690 change=1;
692 if(change==1){
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 memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
699 memcpy(der+p_vet->end,temp,p_vet->end-counter);
700 _asn1_afree(temp);
702 p_vet->end=counter+(p2_vet->end-p_vet->end);
704 counter=p_vet->end;
706 p2_vet=p2_vet->next;
707 p_vet=p_vet->next;
710 if(p_vet!=first) p_vet->prev->next=NULL;
711 else first=NULL;
712 _asn1_afree(p_vet);
713 p_vet=first;
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 inside *POINTER).
721 * @der: vector that will contain the DER encoding. DER must be a pointer to memory cells already allocated.
722 * @len: number of bytes of *der: der[0]..der[len-1], Initialy holds the sizeof of der vector.
723 * @errorDescription : return the error description or an empty string if success.
724 * Description:
726 * Creates the DER encoding for the NAME structure (inside *POINTER structure).
728 * Returns:
730 * ASN1_SUCCESS\: DER encoding OK
732 * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element.
734 * ASN1_VALUE_NOT_FOUND\: there is an element without a value.
736 * ASN1_MEM_ERROR\: der vector isn't big enough. Also in this case LEN
737 * will contain the length needed.
740 asn1_retCode
741 asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len,
742 char *ErrorDescription)
744 node_asn *node,*p;
745 char temp[SIZEOF_UNSIGNED_LONG_INT*3+1];
746 int counter,counter_old,len2,len3,move,max_len,max_len_old;
747 asn1_retCode ris;
749 node=_asn1_find_node(element,name);
750 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
752 max_len=*len;
754 counter=0;
755 move=DOWN;
756 p=node;
757 while(1){
759 counter_old=counter;
760 max_len_old=max_len;
761 if(move!=UP){
762 ris=_asn1_insert_tag_der(p,der,&counter,&max_len);
764 switch(type_field(p->type)){
765 case TYPE_NULL:
766 max_len--;
767 if(max_len>=0)
768 der[counter++]=0;
769 move=RIGHT;
770 break;
771 case TYPE_BOOLEAN:
772 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
773 counter=counter_old;
774 max_len=max_len_old;
776 else{
777 if(p->value==NULL){
778 _asn1_error_description_value_not_found(p,ErrorDescription);
779 return ASN1_VALUE_NOT_FOUND;
781 max_len -= 2;
782 if(max_len>=0){
783 der[counter++]=1;
784 if(p->value[0]=='F') der[counter++]=0;
785 else der[counter++]=0xFF;
788 move=RIGHT;
789 break;
790 case TYPE_INTEGER: case TYPE_ENUMERATED:
791 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
792 counter=counter_old;
793 max_len=max_len_old;
795 else{
796 if(p->value==NULL){
797 _asn1_error_description_value_not_found(p,ErrorDescription);
798 return ASN1_VALUE_NOT_FOUND;
800 len2=_asn1_get_length_der(p->value,&len3);
801 max_len -= len2+len3;
802 if(max_len>=0)
803 memcpy(der+counter,p->value,len3+len2);
804 counter+=len3+len2;
806 move=RIGHT;
807 break;
808 case TYPE_OBJECT_ID:
809 if(p->value==NULL){
810 _asn1_error_description_value_not_found(p,ErrorDescription);
811 return ASN1_VALUE_NOT_FOUND;
813 len2=max_len;
814 ris=_asn1_objectid_der(p->value,der+counter,&len2);
815 max_len-=len2;
816 counter+=len2;
817 move=RIGHT;
818 break;
819 case TYPE_TIME:
820 if(p->value==NULL){
821 _asn1_error_description_value_not_found(p,ErrorDescription);
822 return ASN1_VALUE_NOT_FOUND;
824 len2=max_len;
825 ris=_asn1_time_der(p->value,der+counter,&len2);
826 max_len-=len2;
827 counter+=len2;
828 move=RIGHT;
829 break;
830 case TYPE_OCTET_STRING:
831 if(p->value==NULL){
832 _asn1_error_description_value_not_found(p,ErrorDescription);
833 return ASN1_VALUE_NOT_FOUND;
835 len2=_asn1_get_length_der(p->value,&len3);
836 max_len-=len2+len3;
837 if(max_len>=0)
838 memcpy(der+counter,p->value,len3+len2);
839 counter+=len3+len2;
840 move=RIGHT;
841 break;
842 case TYPE_GENERALSTRING:
843 if(p->value==NULL){
844 _asn1_error_description_value_not_found(p,ErrorDescription);
845 return ASN1_VALUE_NOT_FOUND;
847 len2=_asn1_get_length_der(p->value,&len3);
848 max_len-=len2+len3;
849 if(max_len>=0)
850 memcpy(der+counter,p->value,len3+len2);
851 counter+=len3+len2;
852 move=RIGHT;
853 break;
854 case TYPE_BIT_STRING:
855 if(p->value==NULL){
856 _asn1_error_description_value_not_found(p,ErrorDescription);
857 return ASN1_VALUE_NOT_FOUND;
859 len2=_asn1_get_length_der(p->value,&len3);
860 max_len-=len2+len3;
861 if(max_len>=0)
862 memcpy(der+counter,p->value,len3+len2);
863 counter+=len3+len2;
864 move=RIGHT;
865 break;
866 case TYPE_SEQUENCE: case TYPE_SET:
867 if(move!=UP){
868 _asn1_ltostr(counter,temp);
869 _asn1_set_value(p,temp,strlen(temp)+1);
870 move=DOWN;
872 else{ /* move==UP */
873 len2=strtol(p->value,NULL,10);
874 _asn1_set_value(p,NULL,0);
875 if((type_field(p->type)==TYPE_SET) && (max_len>=0))
876 _asn1_ordering_set(der+len2,p);
877 _asn1_length_der(counter-len2,temp,&len3);
878 max_len-=len3;
879 if(max_len>=0){
880 memmove(der+len2+len3,der+len2,counter-len2);
881 memcpy(der+len2,temp,len3);
883 counter+=len3;
884 move=RIGHT;
886 break;
887 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
888 if(move!=UP){
889 _asn1_ltostr(counter,temp);
890 _asn1_set_value(p,temp,strlen(temp)+1);
891 p=p->down;
892 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
893 if(p->right){
894 p=p->right;
895 move=RIGHT;
896 continue;
898 else p=_asn1_find_up(p);
899 move=UP;
901 if(move==UP){
902 len2=strtol(p->value,NULL,10);
903 _asn1_set_value(p,NULL,0);
904 if((type_field(p->type)==TYPE_SET_OF) && (max_len>=0))
905 _asn1_ordering_set_of(der+len2,p);
906 _asn1_length_der(counter-len2,temp,&len3);
907 max_len-=len3;
908 if(max_len>=0){
909 memmove(der+len2+len3,der+len2,counter-len2);
910 memcpy(der+len2,temp,len3);
912 counter+=len3;
913 move=RIGHT;
915 break;
916 case TYPE_ANY:
917 if(p->value==NULL){
918 _asn1_error_description_value_not_found(p,ErrorDescription);
919 return ASN1_VALUE_NOT_FOUND;
921 len2=_asn1_get_length_der(p->value,&len3);
922 max_len-=len2;
923 if(max_len>=0)
924 memcpy(der+counter,p->value+len3,len2);
925 counter+=len2;
926 move=RIGHT;
927 break;
928 default:
929 move=(move==UP)?RIGHT:DOWN;
930 break;
933 if((move!=DOWN) && (counter!=counter_old)){
934 ris=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
937 if(p==node && move!=DOWN) break;
939 if(move==DOWN){
940 if(p->down) p=p->down;
941 else move=RIGHT;
943 if(move==RIGHT){
944 if(p->right) p=p->right;
945 else move=UP;
947 if(move==UP) p=_asn1_find_up(p);
950 *len=counter;
952 if(max_len<0) return ASN1_MEM_ERROR;
954 return ASN1_SUCCESS;