Update.
[libtasn1.git] / lib / coding.c
blob41c01d9afced00b2aa13774a35d93394da8089bc
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: coding.c */
26 /* Description: Functions to create a DER coding of */
27 /* an ASN1 type. */
28 /*****************************************************/
30 #include <int.h>
31 #include <errors.h>
32 #include "parser_aux.h"
33 #include <gstr.h>
34 #include "element.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. */
42 /* Parameters: */
43 /* node: node of the tree where the value is NULL. */
44 /* ErrorDescription: string returned. */
45 /* Return: */
46 /******************************************************/
47 void
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 * asn1_length_der:
62 * @len: value to convert.
63 * @ans: string returned.
64 * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
66 * Creates the DER coding for the LEN parameter (only the length).
67 * The @ans buffer is pre-allocated and must have room for the output.
68 **/
69 void
70 asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len)
72 int k;
73 unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
75 if(len<128){
76 /* short form */
77 if(ans!=NULL) ans[0]=(unsigned char)len;
78 *ans_len=1;
80 else{
81 /* Long form */
82 k=0;
83 while(len){
84 temp[k++]=len&0xFF;
85 len=len>>8;
87 *ans_len=k+1;
88 if(ans!=NULL){
89 ans[0]=((unsigned char)k&0x7F)+128;
90 while(k--) ans[*ans_len-1-k]=temp[k];
95 /******************************************************/
96 /* Function : _asn1_tag_der */
97 /* Description: creates the DER coding for the CLASS */
98 /* and TAG parameters. */
99 /* Parameters: */
100 /* class: value to convert. */
101 /* tag_value: value to convert. */
102 /* ans: string returned. */
103 /* ans_len: number of meaningful bytes of ANS */
104 /* (ans[0]..ans[ans_len-1]). */
105 /* Return: */
106 /******************************************************/
107 void
108 _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int *ans_len)
110 int k;
111 unsigned char temp[SIZEOF_UNSIGNED_INT];
113 if(tag_value<31){
114 /* short form */
115 ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F));
116 *ans_len=1;
118 else{
119 /* Long form */
120 ans[0]=(class&0xE0) + 31;
121 k=0;
122 while(tag_value){
123 temp[k++]=tag_value&0x7F;
124 tag_value=tag_value>>7;
126 *ans_len=k+1;
127 while(k--) ans[*ans_len-1-k]=temp[k]+128;
128 ans[*ans_len-1]-=128;
133 * asn1_octet_der:
134 * @str: OCTET string.
135 * @str_len: STR length (str[0]..str[str_len-1]).
136 * @der: string returned.
137 * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
139 * Creates the DER coding for an OCTET type (length included).
141 void
142 asn1_octet_der(const unsigned char *str,int str_len,
143 unsigned char *der,int *der_len)
145 int len_len;
147 if(der==NULL || str_len <= 0) return;
148 asn1_length_der(str_len,der,&len_len);
149 memcpy(der+len_len,str,str_len);
150 *der_len=str_len+len_len;
153 /******************************************************/
154 /* Function : _asn1_time_der */
155 /* Description: creates the DER coding for a TIME */
156 /* type (length included). */
157 /* Parameters: */
158 /* str: TIME null-terminated string. */
159 /* der: string returned. */
160 /* der_len: number of meaningful bytes of DER */
161 /* (der[0]..der[ans_len-1]). Initially it */
162 /* if must store the lenght of DER. */
163 /* Return: */
164 /* ASN1_MEM_ERROR when DER isn't big enough */
165 /* ASN1_SUCCESS otherwise */
166 /******************************************************/
167 asn1_retCode
168 _asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
170 int len_len;
171 int max_len;
173 max_len=*der_len;
175 asn1_length_der(strlen(str),(max_len>0)?der:NULL,&len_len);
177 if((len_len+(int)strlen(str))<=max_len)
178 memcpy(der+len_len,str,strlen(str));
179 *der_len=len_len+strlen(str);
181 if((*der_len)>max_len) return ASN1_MEM_ERROR;
183 return ASN1_SUCCESS;
188 void
189 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
191 int len_len,str_len;
192 char temp[20];
194 if(str==NULL) return;
195 str_len=asn1_get_length_der(der,*der_len,&len_len);
196 if (str_len<0) return;
197 memcpy(temp,der+len_len,str_len);
198 *der_len=str_len+len_len;
199 switch(str_len){
200 case 11:
201 temp[10]=0;
202 strcat(temp,"00+0000");
203 break;
204 case 13:
205 temp[12]=0;
206 strcat(temp,"+0000");
207 break;
208 case 15:
209 temp[15]=0;
210 memmove(temp+12,temp+10,6);
211 temp[10]=temp[11]='0';
212 break;
213 case 17:
214 temp[17]=0;
215 break;
216 default:
217 return;
219 strcpy(str,temp);
223 /******************************************************/
224 /* Function : _asn1_objectid_der */
225 /* Description: creates the DER coding for an */
226 /* OBJECT IDENTIFIER type (length included). */
227 /* Parameters: */
228 /* str: OBJECT IDENTIFIER null-terminated string. */
229 /* der: string returned. */
230 /* der_len: number of meaningful bytes of DER */
231 /* (der[0]..der[ans_len-1]). Initially it */
232 /* must store the length of DER. */
233 /* Return: */
234 /* ASN1_MEM_ERROR when DER isn't big enough */
235 /* ASN1_SUCCESS otherwise */
236 /******************************************************/
237 asn1_retCode
238 _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
240 int len_len,counter,k,first,max_len;
241 char *temp,*n_end,*n_start;
242 unsigned char bit7;
243 unsigned long val,val1=0;
245 max_len=*der_len;
247 temp= (char *) _asn1_alloca(strlen(str)+2);
248 if(temp==NULL) return ASN1_MEM_ALLOC_ERROR;
250 strcpy(temp, str);
251 strcat(temp, ".");
253 counter=0;
254 n_start=temp;
255 while((n_end=strchr(n_start,'.'))){
256 *n_end=0;
257 val=strtoul(n_start,NULL,10);
258 counter++;
260 if(counter==1) val1=val;
261 else if(counter==2){
262 if(max_len>0)
263 der[0]=40*val1+val;
264 *der_len=1;
266 else{
267 first=0;
268 for(k=4;k>=0;k--){
269 bit7=(val>>(k*7))&0x7F;
270 if(bit7 || first || !k){
271 if(k) bit7|=0x80;
272 if(max_len>(*der_len))
273 der[*der_len]=bit7;
274 (*der_len)++;
275 first=1;
280 n_start=n_end+1;
283 asn1_length_der(*der_len,NULL,&len_len);
284 if(max_len>=(*der_len+len_len)){
285 memmove(der+len_len,der,*der_len);
286 asn1_length_der(*der_len,der,&len_len);
288 *der_len+=len_len;
290 _asn1_afree(temp);
292 if(max_len<(*der_len)) return ASN1_MEM_ERROR;
294 return ASN1_SUCCESS;
298 const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
301 * asn1_bit_der:
302 * @str: BIT string.
303 * @bit_len: number of meaningful bits in STR.
304 * @der: string returned.
305 * @der_len: number of meaningful bytes of DER
306 * (der[0]..der[ans_len-1]).
308 * Creates the DER coding for a BIT STRING type (length and pad
309 * included).
311 void
312 asn1_bit_der(const unsigned char *str, int bit_len,
313 unsigned char *der, int *der_len)
315 int len_len,len_byte,len_pad;
317 if(der==NULL) return;
318 len_byte=bit_len>>3;
319 len_pad=8-(bit_len&7);
320 if(len_pad==8) len_pad=0;
321 else len_byte++;
322 asn1_length_der(len_byte+1,der,&len_len);
323 der[len_len]=len_pad;
324 memcpy(der+len_len+1,str,len_byte);
325 der[len_len+len_byte]&=bit_mask[len_pad];
326 *der_len=len_byte+len_len+1;
330 /******************************************************/
331 /* Function : _asn1_complete_explicit_tag */
332 /* Description: add the length coding to the EXPLICIT */
333 /* tags. */
334 /* Parameters: */
335 /* node: pointer to the tree element. */
336 /* der: string with the DER coding of the whole tree*/
337 /* counter: number of meaningful bytes of DER */
338 /* (der[0]..der[*counter-1]). */
339 /* max_len: size of der vector */
340 /* Return: */
341 /* ASN1_MEM_ERROR if der vector isn't big enough, */
342 /* otherwise ASN1_SUCCESS. */
343 /******************************************************/
344 asn1_retCode
345 _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len)
347 node_asn *p;
348 int is_tag_implicit,len2,len3;
349 unsigned char temp[SIZEOF_UNSIGNED_INT];
351 is_tag_implicit=0;
353 if(node->type&CONST_TAG){
354 p=node->down;
355 /* When there are nested tags we must complete them reverse to
356 the order they were created. This is because completing a tag
357 modifies all data within it, including the incomplete tags
358 which store buffer positions -- simon@josefsson.org 2002-09-06
360 while(p->right)
361 p=p->right;
362 while(p && p!=node->down->left){
363 if(type_field(p->type)==TYPE_TAG){
364 if(p->type&CONST_EXPLICIT){
365 len2=strtol(p->name,NULL,10);
366 _asn1_set_name(p,NULL);
367 asn1_length_der(*counter-len2,temp,&len3);
368 if(len3<=(*max_len)){
369 memmove(der+len2+len3,der+len2,*counter-len2);
370 memcpy(der+len2,temp,len3);
372 *max_len -= len3;
373 *counter+=len3;
374 is_tag_implicit=0;
376 else{ /* CONST_IMPLICIT */
377 if(!is_tag_implicit){
378 is_tag_implicit=1;
382 p=p->left;
386 if(*max_len<0) return ASN1_MEM_ERROR;
388 return ASN1_SUCCESS;
392 /******************************************************/
393 /* Function : _asn1_insert_tag_der */
394 /* Description: creates the DER coding of tags of one */
395 /* NODE. */
396 /* Parameters: */
397 /* node: pointer to the tree element. */
398 /* der: string returned */
399 /* counter: number of meaningful bytes of DER */
400 /* (counter[0]..der[*counter-1]). */
401 /* max_len: size of der vector */
402 /* Return: */
403 /* ASN1_GENERIC_ERROR if the type is unknown, */
404 /* ASN1_MEM_ERROR if der vector isn't big enough, */
405 /* otherwise ASN1_SUCCESS. */
406 /******************************************************/
407 asn1_retCode
408 _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len)
410 node_asn *p;
411 int tag_len,is_tag_implicit;
412 unsigned char class,class_implicit=0,temp[SIZEOF_UNSIGNED_INT*3+1];
413 unsigned long tag_implicit=0;
414 char tag_der[MAX_TAG_LEN];
416 is_tag_implicit=0;
418 if(node->type&CONST_TAG){
419 p=node->down;
420 while(p){
421 if(type_field(p->type)==TYPE_TAG){
422 if(p->type&CONST_APPLICATION) class=ASN1_CLASS_APPLICATION;
423 else if(p->type&CONST_UNIVERSAL) class=ASN1_CLASS_UNIVERSAL;
424 else if(p->type&CONST_PRIVATE) class=ASN1_CLASS_PRIVATE;
425 else class=ASN1_CLASS_CONTEXT_SPECIFIC;
427 if(p->type&CONST_EXPLICIT){
428 if(is_tag_implicit)
429 _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
430 else
431 _asn1_tag_der(class|ASN1_CLASS_STRUCTURED,strtoul(p->value,NULL,10),tag_der,&tag_len);
433 *max_len -= tag_len;
434 if(*max_len>=0)
435 memcpy(der+*counter,tag_der,tag_len);
436 *counter+=tag_len;
438 _asn1_ltostr(*counter,temp);
439 _asn1_set_name(p,temp);
441 is_tag_implicit=0;
443 else{ /* CONST_IMPLICIT */
444 if(!is_tag_implicit){
445 if((type_field(node->type)==TYPE_SEQUENCE) ||
446 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
447 (type_field(node->type)==TYPE_SET) ||
448 (type_field(node->type)==TYPE_SET_OF)) class|=ASN1_CLASS_STRUCTURED;
449 class_implicit=class;
450 tag_implicit=strtoul(p->value,NULL,10);
451 is_tag_implicit=1;
455 p=p->right;
459 if(is_tag_implicit){
460 _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
462 else{
463 switch(type_field(node->type)){
464 case TYPE_NULL:
465 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_NULL,tag_der,&tag_len);
466 break;
467 case TYPE_BOOLEAN:
468 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BOOLEAN,tag_der,&tag_len);
469 break;
470 case TYPE_INTEGER:
471 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_INTEGER,tag_der,&tag_len);
472 break;
473 case TYPE_ENUMERATED:
474 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_ENUMERATED,tag_der,&tag_len);
475 break;
476 case TYPE_OBJECT_ID:
477 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OBJECT_ID,tag_der,&tag_len);
478 break;
479 case TYPE_TIME:
480 if(node->type&CONST_UTC){
481 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_UTCTime,tag_der,&tag_len);
483 else _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALIZEDTime,tag_der,&tag_len);
484 break;
485 case TYPE_OCTET_STRING:
486 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OCTET_STRING,tag_der,&tag_len);
487 break;
488 case TYPE_GENERALSTRING:
489 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALSTRING,tag_der,&tag_len);
490 break;
491 case TYPE_BIT_STRING:
492 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BIT_STRING,tag_der,&tag_len);
493 break;
494 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
495 _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SEQUENCE,tag_der,&tag_len);
496 break;
497 case TYPE_SET: case TYPE_SET_OF:
498 _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SET,tag_der,&tag_len);
499 break;
500 case TYPE_TAG:
501 tag_len=0;
502 break;
503 case TYPE_CHOICE:
504 tag_len=0;
505 break;
506 case TYPE_ANY:
507 tag_len=0;
508 break;
509 default:
510 return ASN1_GENERIC_ERROR;
514 *max_len -= tag_len;
515 if(*max_len>=0)
516 memcpy(der+*counter,tag_der,tag_len);
517 *counter+=tag_len;
519 if(*max_len<0) return ASN1_MEM_ERROR;
521 return ASN1_SUCCESS;
524 /******************************************************/
525 /* Function : _asn1_ordering_set */
526 /* Description: puts the elements of a SET type in */
527 /* the correct order according to DER rules. */
528 /* Parameters: */
529 /* der: string with the DER coding. */
530 /* node: pointer to the SET element. */
531 /* Return: */
532 /******************************************************/
533 void
534 _asn1_ordering_set(unsigned char *der, int der_len, node_asn *node)
536 struct vet{
537 int end;
538 unsigned long value;
539 struct vet *next,*prev;
542 int counter,len,len2;
543 struct vet *first,*last,*p_vet,*p2_vet;
544 node_asn *p;
545 unsigned char class,*temp;
546 unsigned long tag;
548 counter=0;
550 if(type_field(node->type)!=TYPE_SET) return;
552 p=node->down;
553 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
555 if((p==NULL) || (p->right==NULL)) return;
557 first=last=NULL;
558 while(p){
559 p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
560 if (p_vet==NULL) return;
562 p_vet->next=NULL;
563 p_vet->prev=last;
564 if(first==NULL) first=p_vet;
565 else last->next=p_vet;
566 last=p_vet;
568 /* tag value calculation */
569 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
570 return;
571 p_vet->value=(class<<24)|tag;
572 counter+=len2;
574 /* extraction and length */
575 len2=asn1_get_length_der(der+counter,der_len-counter,&len);
576 if (len2<0) return;
577 counter+=len+len2;
579 p_vet->end=counter;
580 p=p->right;
583 p_vet=first;
585 while(p_vet){
586 p2_vet=p_vet->next;
587 counter=0;
588 while(p2_vet){
589 if(p_vet->value>p2_vet->value){
590 /* change position */
591 temp=(unsigned char *)_asn1_alloca( p_vet->end-counter);
592 if (temp==NULL) return;
594 memcpy(temp,der+counter,p_vet->end-counter);
595 memcpy(der+counter,der+p_vet->end,p2_vet->end-p_vet->end);
596 memcpy(der+counter+p2_vet->end-p_vet->end,temp,p_vet->end-counter);
597 _asn1_afree(temp);
599 tag=p_vet->value;
600 p_vet->value=p2_vet->value;
601 p2_vet->value=tag;
603 p_vet->end=counter+(p2_vet->end-p_vet->end);
605 counter=p_vet->end;
607 p2_vet=p2_vet->next;
608 p_vet=p_vet->next;
611 if(p_vet!=first) p_vet->prev->next=NULL;
612 else first=NULL;
613 _asn1_afree(p_vet);
614 p_vet=first;
618 /******************************************************/
619 /* Function : _asn1_ordering_set_of */
620 /* Description: puts the elements of a SET OF type in */
621 /* the correct order according to DER rules. */
622 /* Parameters: */
623 /* der: string with the DER coding. */
624 /* node: pointer to the SET OF element. */
625 /* Return: */
626 /******************************************************/
627 void
628 _asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node)
630 struct vet{
631 int end;
632 struct vet *next,*prev;
635 int counter,len,len2,change;
636 struct vet *first,*last,*p_vet,*p2_vet;
637 node_asn *p;
638 unsigned char *temp,class;
639 unsigned long k,max;
641 counter=0;
643 if(type_field(node->type)!=TYPE_SET_OF) return;
645 p=node->down;
646 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
647 p=p->right;
649 if((p==NULL) || (p->right==NULL)) return;
651 first=last=NULL;
652 while(p){
653 p_vet=(struct vet *)_asn1_alloca(sizeof(struct vet));
654 if (p_vet==NULL) return;
656 p_vet->next=NULL;
657 p_vet->prev=last;
658 if(first==NULL) first=p_vet;
659 else last->next=p_vet;
660 last=p_vet;
662 /* extraction of tag and length */
663 if (der_len-counter > 0) {
665 if (asn1_get_tag_der(der+counter, der_len - counter, &class,&len,NULL)!=ASN1_SUCCESS)
666 return;
667 counter+=len;
669 len2=asn1_get_length_der(der+counter,der_len-counter,&len);
670 if (len2<0) return;
671 counter+=len+len2;
674 p_vet->end=counter;
675 p=p->right;
678 p_vet=first;
680 while(p_vet){
681 p2_vet=p_vet->next;
682 counter=0;
683 while(p2_vet){
684 if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
685 max=p_vet->end-counter;
686 else
687 max=p2_vet->end-p_vet->end;
689 change=-1;
690 for(k=0;k<max;k++)
691 if(der[counter+k]>der[p_vet->end+k]){change=1;break;}
692 else if(der[counter+k]<der[p_vet->end+k]){change=0;break;}
694 if((change==-1) && ((p_vet->end-counter)>(p2_vet->end-p_vet->end)))
695 change=1;
697 if(change==1){
698 /* change position */
699 temp=(unsigned char *)_asn1_alloca(p_vet->end-counter);
700 if (temp==NULL) return;
702 memcpy(temp,der+counter,(p_vet->end)-counter);
703 memcpy(der+counter,der+(p_vet->end),(p2_vet->end)-(p_vet->end));
704 memcpy(der+counter+(p2_vet->end)-(p_vet->end),temp,(p_vet->end)-counter);
705 _asn1_afree(temp);
707 p_vet->end=counter+(p2_vet->end-p_vet->end);
709 counter=p_vet->end;
711 p2_vet=p2_vet->next;
712 p_vet=p_vet->next;
715 if(p_vet!=first) p_vet->prev->next=NULL;
716 else first=NULL;
717 _asn1_afree(p_vet);
718 p_vet=first;
723 * asn1_der_coding - Creates the DER encoding for the NAME structure
724 * @element: pointer to an ASN1 element
725 * @name: the name of the structure you want to encode (it must be
726 * inside *POINTER).
727 * @ider: vector that will contain the DER encoding. DER must be a
728 * pointer to memory cells already allocated.
729 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
730 * holds the sizeof of der vector.
731 * @errorDescription : return the error description or an empty
732 * string if success.
734 * Creates the DER encoding for the NAME structure (inside *POINTER
735 * structure).
737 * Returns:
739 * ASN1_SUCCESS: DER encoding OK.
741 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
743 * ASN1_VALUE_NOT_FOUND: There is an element without a value.
745 * ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
746 * LEN will contain the length needed.
749 asn1_retCode
750 asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
751 char *ErrorDescription)
753 node_asn *node,*p,*p2;
754 char temp[SIZEOF_UNSIGNED_LONG_INT*3+1];
755 int counter,counter_old,len2,len3,tlen,move,max_len,max_len_old;
756 asn1_retCode ris;
757 unsigned char* der = ider;
759 node=_asn1_find_node(element,name);
760 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
762 max_len=*len;
764 counter=0;
765 move=DOWN;
766 p=node;
767 while(1){
769 counter_old=counter;
770 max_len_old=max_len;
771 if(move!=UP){
772 ris=_asn1_insert_tag_der(p,der,&counter,&max_len);
774 switch(type_field(p->type)){
775 case TYPE_NULL:
776 max_len--;
777 if(max_len>=0)
778 der[counter++]=0;
779 move=RIGHT;
780 break;
781 case TYPE_BOOLEAN:
782 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
783 counter=counter_old;
784 max_len=max_len_old;
786 else{
787 if(p->value==NULL){
788 _asn1_error_description_value_not_found(p,ErrorDescription);
789 return ASN1_VALUE_NOT_FOUND;
791 max_len -= 2;
792 if(max_len>=0){
793 der[counter++]=1;
794 if(p->value[0]=='F') der[counter++]=0;
795 else der[counter++]=0xFF;
797 else
798 counter+=2;
800 move=RIGHT;
801 break;
802 case TYPE_INTEGER: case TYPE_ENUMERATED:
803 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
804 counter=counter_old;
805 max_len=max_len_old;
807 else{
808 if(p->value==NULL){
809 _asn1_error_description_value_not_found(p,ErrorDescription);
810 return ASN1_VALUE_NOT_FOUND;
812 len2=asn1_get_length_der(p->value,p->value_len, &len3);
813 if (len2<0) return ASN1_DER_ERROR;
814 max_len -= len2+len3;
815 if(max_len>=0)
816 memcpy(der+counter,p->value,len3+len2);
817 counter+=len3+len2;
819 move=RIGHT;
820 break;
821 case TYPE_OBJECT_ID:
822 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
823 counter=counter_old;
824 max_len=max_len_old;
826 else{
827 if(p->value==NULL){
828 _asn1_error_description_value_not_found(p,ErrorDescription);
829 return ASN1_VALUE_NOT_FOUND;
831 len2=max_len;
832 ris=_asn1_objectid_der(p->value,der+counter,&len2);
833 if(ris==ASN1_MEM_ALLOC_ERROR) return ris;
834 max_len-=len2;
835 counter+=len2;
837 move=RIGHT;
838 break;
839 case TYPE_TIME:
840 if(p->value==NULL){
841 _asn1_error_description_value_not_found(p,ErrorDescription);
842 return ASN1_VALUE_NOT_FOUND;
844 len2=max_len;
845 ris=_asn1_time_der(p->value,der+counter,&len2);
846 max_len-=len2;
847 counter+=len2;
848 move=RIGHT;
849 break;
850 case TYPE_OCTET_STRING:
851 if(p->value==NULL){
852 _asn1_error_description_value_not_found(p,ErrorDescription);
853 return ASN1_VALUE_NOT_FOUND;
855 len2=asn1_get_length_der(p->value,p->value_len,&len3);
856 if (len2<0) return ASN1_DER_ERROR;
857 max_len-=len2+len3;
858 if(max_len>=0)
859 memcpy(der+counter,p->value,len3+len2);
860 counter+=len3+len2;
861 move=RIGHT;
862 break;
863 case TYPE_GENERALSTRING:
864 if(p->value==NULL){
865 _asn1_error_description_value_not_found(p,ErrorDescription);
866 return ASN1_VALUE_NOT_FOUND;
868 len2=asn1_get_length_der(p->value,p->value_len,&len3);
869 if (len2<0) return ASN1_DER_ERROR;
870 max_len-=len2+len3;
871 if(max_len>=0)
872 memcpy(der+counter,p->value,len3+len2);
873 counter+=len3+len2;
874 move=RIGHT;
875 break;
876 case TYPE_BIT_STRING:
877 if(p->value==NULL){
878 _asn1_error_description_value_not_found(p,ErrorDescription);
879 return ASN1_VALUE_NOT_FOUND;
881 len2=asn1_get_length_der(p->value,p->value_len,&len3);
882 if (len2<0) return ASN1_DER_ERROR;
883 max_len-=len2+len3;
884 if(max_len>=0)
885 memcpy(der+counter,p->value,len3+len2);
886 counter+=len3+len2;
887 move=RIGHT;
888 break;
889 case TYPE_SEQUENCE: case TYPE_SET:
890 if(move!=UP){
891 _asn1_ltostr(counter,temp);
892 tlen = strlen(temp);
893 if (tlen > 0)
894 _asn1_set_value(p,temp,tlen+1);
895 if(p->down==NULL){
896 move=UP;
897 continue;
899 else{
900 p2=p->down;
901 while(p2 && (type_field(p2->type)==TYPE_TAG)) p2=p2->right;
902 if(p2){
903 p=p2;
904 move=RIGHT;
905 continue;
907 move=UP;
908 continue;
911 else{ /* move==UP */
912 len2=strtol(p->value,NULL,10);
913 _asn1_set_value(p,NULL,0);
914 if((type_field(p->type)==TYPE_SET) && (max_len>=0))
915 _asn1_ordering_set(der+len2, max_len-len2,p);
916 asn1_length_der(counter-len2,temp,&len3);
917 max_len-=len3;
918 if(max_len>=0){
919 memmove(der+len2+len3,der+len2,counter-len2);
920 memcpy(der+len2,temp,len3);
922 counter+=len3;
923 move=RIGHT;
925 break;
926 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
927 if(move!=UP){
928 _asn1_ltostr(counter,temp);
929 tlen = strlen(temp);
931 if (tlen > 0)
932 _asn1_set_value(p,temp,tlen+1);
933 p=p->down;
934 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
935 if(p->right){
936 p=p->right;
937 move=RIGHT;
938 continue;
940 else p=_asn1_find_up(p);
941 move=UP;
943 if(move==UP){
944 len2=strtol(p->value,NULL,10);
945 _asn1_set_value(p,NULL,0);
946 if((type_field(p->type)==TYPE_SET_OF) && (max_len-len2>0)) {
947 _asn1_ordering_set_of(der+len2, max_len-len2,p);
949 asn1_length_der(counter-len2,temp,&len3);
950 max_len-=len3;
951 if(max_len>=0){
952 memmove(der+len2+len3,der+len2,counter-len2);
953 memcpy(der+len2,temp,len3);
955 counter+=len3;
956 move=RIGHT;
958 break;
959 case TYPE_ANY:
960 if(p->value==NULL){
961 _asn1_error_description_value_not_found(p,ErrorDescription);
962 return ASN1_VALUE_NOT_FOUND;
964 len2=asn1_get_length_der(p->value,p->value_len,&len3);
965 if (len2<0) return ASN1_DER_ERROR;
966 max_len-=len2;
967 if(max_len>=0)
968 memcpy(der+counter,p->value+len3,len2);
969 counter+=len2;
970 move=RIGHT;
971 break;
972 default:
973 move=(move==UP)?RIGHT:DOWN;
974 break;
977 if((move!=DOWN) && (counter!=counter_old)){
978 ris=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
981 if(p==node && move!=DOWN) break;
983 if(move==DOWN){
984 if(p->down) p=p->down;
985 else move=RIGHT;
987 if(move==RIGHT){
988 if(p->right) p=p->right;
989 else move=UP;
991 if(move==UP) p=_asn1_find_up(p);
994 *len=counter;
996 if(max_len<0) return ASN1_MEM_ERROR;
998 return ASN1_SUCCESS;