Update.
[libtasn1.git] / lib / coding.c
blobaa19d20ef24be0cba1a0d5726ffda57ca8d2bc44
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"
35 #include <structure.h>
37 #define MAX_TAG_LEN 16
39 /******************************************************/
40 /* Function : _asn1_error_description_value_not_found */
41 /* Description: creates the ErrorDescription string */
42 /* for the ASN1_VALUE_NOT_FOUND error. */
43 /* Parameters: */
44 /* node: node of the tree where the value is NULL. */
45 /* ErrorDescription: string returned. */
46 /* Return: */
47 /******************************************************/
48 void
49 _asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription)
52 if (ErrorDescription == NULL) return;
54 Estrcpy(ErrorDescription,":: value of element '");
55 _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
56 MAX_ERROR_DESCRIPTION_SIZE-40);
57 Estrcat(ErrorDescription,"' not found");
61 /**
62 * asn1_length_der:
63 * @len: value to convert.
64 * @ans: string returned.
65 * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
67 * Creates the DER coding for the LEN parameter (only the length).
68 * The @ans buffer is pre-allocated and must have room for the output.
69 **/
70 void
71 asn1_length_der(unsigned long int 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 meaningful 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<31){
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;
134 * asn1_octet_der:
135 * @str: OCTET string.
136 * @str_len: STR length (str[0]..str[str_len-1]).
137 * @der: string returned.
138 * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
140 * Creates the DER coding for an OCTET type (length included).
142 void
143 asn1_octet_der(const unsigned char *str,int str_len,
144 unsigned char *der,int *der_len)
146 int len_len;
148 if(der==NULL || str_len <= 0) return;
149 asn1_length_der(str_len,der,&len_len);
150 memcpy(der+len_len,str,str_len);
151 *der_len=str_len+len_len;
154 /******************************************************/
155 /* Function : _asn1_time_der */
156 /* Description: creates the DER coding for a TIME */
157 /* type (length included). */
158 /* Parameters: */
159 /* str: TIME null-terminated string. */
160 /* der: string returned. */
161 /* der_len: number of meaningful bytes of DER */
162 /* (der[0]..der[ans_len-1]). Initially it */
163 /* if must store the lenght of DER. */
164 /* Return: */
165 /* ASN1_MEM_ERROR when DER isn't big enough */
166 /* ASN1_SUCCESS otherwise */
167 /******************************************************/
168 asn1_retCode
169 _asn1_time_der(unsigned char *str,unsigned char *der,int *der_len)
171 int len_len;
172 int max_len;
174 max_len=*der_len;
176 asn1_length_der(strlen(str),(max_len>0)?der:NULL,&len_len);
178 if((len_len+(int)strlen(str))<=max_len)
179 memcpy(der+len_len,str,strlen(str));
180 *der_len=len_len+strlen(str);
182 if((*der_len)>max_len) return ASN1_MEM_ERROR;
184 return ASN1_SUCCESS;
189 void
190 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
192 int len_len,str_len;
193 char temp[20];
195 if(str==NULL) return;
196 str_len=asn1_get_length_der(der,*der_len,&len_len);
197 if (str_len<0) return;
198 memcpy(temp,der+len_len,str_len);
199 *der_len=str_len+len_len;
200 switch(str_len){
201 case 11:
202 temp[10]=0;
203 strcat(temp,"00+0000");
204 break;
205 case 13:
206 temp[12]=0;
207 strcat(temp,"+0000");
208 break;
209 case 15:
210 temp[15]=0;
211 memmove(temp+12,temp+10,6);
212 temp[10]=temp[11]='0';
213 break;
214 case 17:
215 temp[17]=0;
216 break;
217 default:
218 return;
220 strcpy(str,temp);
224 /******************************************************/
225 /* Function : _asn1_objectid_der */
226 /* Description: creates the DER coding for an */
227 /* OBJECT IDENTIFIER type (length included). */
228 /* Parameters: */
229 /* str: OBJECT IDENTIFIER null-terminated string. */
230 /* der: string returned. */
231 /* der_len: number of meaningful bytes of DER */
232 /* (der[0]..der[ans_len-1]). Initially it */
233 /* must store the length of DER. */
234 /* Return: */
235 /* ASN1_MEM_ERROR when DER isn't big enough */
236 /* ASN1_SUCCESS otherwise */
237 /******************************************************/
238 asn1_retCode
239 _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len)
241 int len_len,counter,k,first,max_len;
242 char *temp,*n_end,*n_start;
243 unsigned char bit7;
244 unsigned long val,val1=0;
246 max_len=*der_len;
248 temp= (char *) _asn1_alloca(strlen(str)+2);
249 if(temp==NULL) return ASN1_MEM_ALLOC_ERROR;
251 strcpy(temp, str);
252 strcat(temp, ".");
254 counter=0;
255 n_start=temp;
256 while((n_end=strchr(n_start,'.'))){
257 *n_end=0;
258 val=strtoul(n_start,NULL,10);
259 counter++;
261 if(counter==1) val1=val;
262 else if(counter==2){
263 if(max_len>0)
264 der[0]=40*val1+val;
265 *der_len=1;
267 else{
268 first=0;
269 for(k=4;k>=0;k--){
270 bit7=(val>>(k*7))&0x7F;
271 if(bit7 || first || !k){
272 if(k) bit7|=0x80;
273 if(max_len>(*der_len))
274 der[*der_len]=bit7;
275 (*der_len)++;
276 first=1;
281 n_start=n_end+1;
284 asn1_length_der(*der_len,NULL,&len_len);
285 if(max_len>=(*der_len+len_len)){
286 memmove(der+len_len,der,*der_len);
287 asn1_length_der(*der_len,der,&len_len);
289 *der_len+=len_len;
291 _asn1_afree(temp);
293 if(max_len<(*der_len)) return ASN1_MEM_ERROR;
295 return ASN1_SUCCESS;
299 const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80};
302 * asn1_bit_der:
303 * @str: BIT string.
304 * @bit_len: number of meaningful bits in STR.
305 * @der: string returned.
306 * @der_len: number of meaningful bytes of DER
307 * (der[0]..der[ans_len-1]).
309 * Creates the DER coding for a BIT STRING type (length and pad
310 * included).
312 void
313 asn1_bit_der(const unsigned char *str, int bit_len,
314 unsigned char *der, int *der_len)
316 int len_len,len_byte,len_pad;
318 if(der==NULL) return;
319 len_byte=bit_len>>3;
320 len_pad=8-(bit_len&7);
321 if(len_pad==8) len_pad=0;
322 else len_byte++;
323 asn1_length_der(len_byte+1,der,&len_len);
324 der[len_len]=len_pad;
325 memcpy(der+len_len+1,str,len_byte);
326 der[len_len+len_byte]&=bit_mask[len_pad];
327 *der_len=len_byte+len_len+1;
331 /******************************************************/
332 /* Function : _asn1_complete_explicit_tag */
333 /* Description: add the length coding to the EXPLICIT */
334 /* tags. */
335 /* Parameters: */
336 /* node: pointer to the tree element. */
337 /* der: string with the DER coding of the whole tree*/
338 /* counter: number of meaningful bytes of DER */
339 /* (der[0]..der[*counter-1]). */
340 /* max_len: size of der vector */
341 /* Return: */
342 /* ASN1_MEM_ERROR if der vector isn't big enough, */
343 /* otherwise ASN1_SUCCESS. */
344 /******************************************************/
345 asn1_retCode
346 _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len)
348 node_asn *p;
349 int is_tag_implicit,len2,len3;
350 unsigned char temp[SIZEOF_UNSIGNED_INT];
352 is_tag_implicit=0;
354 if(node->type&CONST_TAG){
355 p=node->down;
356 /* When there are nested tags we must complete them reverse to
357 the order they were created. This is because completing a tag
358 modifies all data within it, including the incomplete tags
359 which store buffer positions -- simon@josefsson.org 2002-09-06
361 while(p->right)
362 p=p->right;
363 while(p && p!=node->down->left){
364 if(type_field(p->type)==TYPE_TAG){
365 if(p->type&CONST_EXPLICIT){
366 len2=strtol(p->name,NULL,10);
367 _asn1_set_name(p,NULL);
368 asn1_length_der(*counter-len2,temp,&len3);
369 if(len3<=(*max_len)){
370 memmove(der+len2+len3,der+len2,*counter-len2);
371 memcpy(der+len2,temp,len3);
373 *max_len -= len3;
374 *counter+=len3;
375 is_tag_implicit=0;
377 else{ /* CONST_IMPLICIT */
378 if(!is_tag_implicit){
379 is_tag_implicit=1;
383 p=p->left;
387 if(*max_len<0) return ASN1_MEM_ERROR;
389 return ASN1_SUCCESS;
393 /******************************************************/
394 /* Function : _asn1_insert_tag_der */
395 /* Description: creates the DER coding of tags of one */
396 /* NODE. */
397 /* Parameters: */
398 /* node: pointer to the tree element. */
399 /* der: string returned */
400 /* counter: number of meaningful bytes of DER */
401 /* (counter[0]..der[*counter-1]). */
402 /* max_len: size of der vector */
403 /* Return: */
404 /* ASN1_GENERIC_ERROR if the type is unknown, */
405 /* ASN1_MEM_ERROR if der vector isn't big enough, */
406 /* otherwise ASN1_SUCCESS. */
407 /******************************************************/
408 asn1_retCode
409 _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len)
411 node_asn *p;
412 int tag_len,is_tag_implicit;
413 unsigned char class,class_implicit=0,temp[SIZEOF_UNSIGNED_INT*3+1];
414 unsigned long tag_implicit=0;
415 char tag_der[MAX_TAG_LEN];
417 is_tag_implicit=0;
419 if(node->type&CONST_TAG){
420 p=node->down;
421 while(p){
422 if(type_field(p->type)==TYPE_TAG){
423 if(p->type&CONST_APPLICATION) class=ASN1_CLASS_APPLICATION;
424 else if(p->type&CONST_UNIVERSAL) class=ASN1_CLASS_UNIVERSAL;
425 else if(p->type&CONST_PRIVATE) class=ASN1_CLASS_PRIVATE;
426 else class=ASN1_CLASS_CONTEXT_SPECIFIC;
428 if(p->type&CONST_EXPLICIT){
429 if(is_tag_implicit)
430 _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
431 else
432 _asn1_tag_der(class|ASN1_CLASS_STRUCTURED,strtoul(p->value,NULL,10),tag_der,&tag_len);
434 *max_len -= tag_len;
435 if(*max_len>=0)
436 memcpy(der+*counter,tag_der,tag_len);
437 *counter+=tag_len;
439 _asn1_ltostr(*counter,temp);
440 _asn1_set_name(p,temp);
442 is_tag_implicit=0;
444 else{ /* CONST_IMPLICIT */
445 if(!is_tag_implicit){
446 if((type_field(node->type)==TYPE_SEQUENCE) ||
447 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
448 (type_field(node->type)==TYPE_SET) ||
449 (type_field(node->type)==TYPE_SET_OF)) class|=ASN1_CLASS_STRUCTURED;
450 class_implicit=class;
451 tag_implicit=strtoul(p->value,NULL,10);
452 is_tag_implicit=1;
456 p=p->right;
460 if(is_tag_implicit){
461 _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len);
463 else{
464 switch(type_field(node->type)){
465 case TYPE_NULL:
466 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_NULL,tag_der,&tag_len);
467 break;
468 case TYPE_BOOLEAN:
469 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BOOLEAN,tag_der,&tag_len);
470 break;
471 case TYPE_INTEGER:
472 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_INTEGER,tag_der,&tag_len);
473 break;
474 case TYPE_ENUMERATED:
475 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_ENUMERATED,tag_der,&tag_len);
476 break;
477 case TYPE_OBJECT_ID:
478 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OBJECT_ID,tag_der,&tag_len);
479 break;
480 case TYPE_TIME:
481 if(node->type&CONST_UTC){
482 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_UTCTime,tag_der,&tag_len);
484 else _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALIZEDTime,tag_der,&tag_len);
485 break;
486 case TYPE_OCTET_STRING:
487 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OCTET_STRING,tag_der,&tag_len);
488 break;
489 case TYPE_GENERALSTRING:
490 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALSTRING,tag_der,&tag_len);
491 break;
492 case TYPE_BIT_STRING:
493 _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BIT_STRING,tag_der,&tag_len);
494 break;
495 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
496 _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SEQUENCE,tag_der,&tag_len);
497 break;
498 case TYPE_SET: case TYPE_SET_OF:
499 _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SET,tag_der,&tag_len);
500 break;
501 case TYPE_TAG:
502 tag_len=0;
503 break;
504 case TYPE_CHOICE:
505 tag_len=0;
506 break;
507 case TYPE_ANY:
508 tag_len=0;
509 break;
510 default:
511 return ASN1_GENERIC_ERROR;
515 *max_len -= tag_len;
516 if(*max_len>=0)
517 memcpy(der+*counter,tag_der,tag_len);
518 *counter+=tag_len;
520 if(*max_len<0) return ASN1_MEM_ERROR;
522 return ASN1_SUCCESS;
525 /******************************************************/
526 /* Function : _asn1_ordering_set */
527 /* Description: puts the elements of a SET type in */
528 /* the correct order according to DER rules. */
529 /* Parameters: */
530 /* der: string with the DER coding. */
531 /* node: pointer to the SET element. */
532 /* Return: */
533 /******************************************************/
534 void
535 _asn1_ordering_set(unsigned char *der, int der_len, node_asn *node)
537 struct vet{
538 int end;
539 unsigned long value;
540 struct vet *next,*prev;
543 int counter,len,len2;
544 struct vet *first,*last,*p_vet,*p2_vet;
545 node_asn *p;
546 unsigned char class,*temp;
547 unsigned long tag;
549 counter=0;
551 if(type_field(node->type)!=TYPE_SET) return;
553 p=node->down;
554 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
556 if((p==NULL) || (p->right==NULL)) return;
558 first=last=NULL;
559 while(p){
560 p_vet=(struct vet *)_asn1_alloca( sizeof(struct vet));
561 if (p_vet==NULL) return;
563 p_vet->next=NULL;
564 p_vet->prev=last;
565 if(first==NULL) first=p_vet;
566 else last->next=p_vet;
567 last=p_vet;
569 /* tag value calculation */
570 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
571 return;
572 p_vet->value=(class<<24)|tag;
573 counter+=len2;
575 /* extraction and length */
576 len2=asn1_get_length_der(der+counter,der_len-counter,&len);
577 if (len2<0) return;
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 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);
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, int der_len, 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 if (der_len-counter > 0) {
666 if (asn1_get_tag_der(der+counter, der_len - counter, &class,&len,NULL)!=ASN1_SUCCESS)
667 return;
668 counter+=len;
670 len2=asn1_get_length_der(der+counter,der_len-counter,&len);
671 if (len2<0) return;
672 counter+=len+len2;
675 p_vet->end=counter;
676 p=p->right;
679 p_vet=first;
681 while(p_vet){
682 p2_vet=p_vet->next;
683 counter=0;
684 while(p2_vet){
685 if((p_vet->end-counter)>(p2_vet->end-p_vet->end))
686 max=p_vet->end-counter;
687 else
688 max=p2_vet->end-p_vet->end;
690 change=-1;
691 for(k=0;k<max;k++)
692 if(der[counter+k]>der[p_vet->end+k]){change=1;break;}
693 else if(der[counter+k]<der[p_vet->end+k]){change=0;break;}
695 if((change==-1) && ((p_vet->end-counter)>(p2_vet->end-p_vet->end)))
696 change=1;
698 if(change==1){
699 /* change position */
700 temp=(unsigned char *)_asn1_alloca(p_vet->end-counter);
701 if (temp==NULL) return;
703 memcpy(temp,der+counter,(p_vet->end)-counter);
704 memcpy(der+counter,der+(p_vet->end),(p2_vet->end)-(p_vet->end));
705 memcpy(der+counter+(p2_vet->end)-(p_vet->end),temp,(p_vet->end)-counter);
706 _asn1_afree(temp);
708 p_vet->end=counter+(p2_vet->end-p_vet->end);
710 counter=p_vet->end;
712 p2_vet=p2_vet->next;
713 p_vet=p_vet->next;
716 if(p_vet!=first) p_vet->prev->next=NULL;
717 else first=NULL;
718 _asn1_afree(p_vet);
719 p_vet=first;
724 * asn1_der_coding - Creates the DER encoding for the NAME structure
725 * @element: pointer to an ASN1 element
726 * @name: the name of the structure you want to encode (it must be
727 * inside *POINTER).
728 * @ider: vector that will contain the DER encoding. DER must be a
729 * pointer to memory cells already allocated.
730 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
731 * holds the sizeof of der vector.
732 * @errorDescription : return the error description or an empty
733 * string if success.
735 * Creates the DER encoding for the NAME structure (inside *POINTER
736 * structure).
738 * Returns:
740 * ASN1_SUCCESS: DER encoding OK.
742 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
744 * ASN1_VALUE_NOT_FOUND: There is an element without a value.
746 * ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
747 * LEN will contain the length needed.
750 asn1_retCode
751 asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len,
752 char *ErrorDescription)
754 node_asn *node,*p,*p2;
755 char temp[SIZEOF_UNSIGNED_LONG_INT*3+1];
756 int counter,counter_old,len2,len3,tlen,move,max_len,max_len_old;
757 asn1_retCode err;
758 unsigned char* der = ider;
760 node=asn1_find_node(element,name);
761 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
763 /* Node is now a locally allocated variable.
764 * That is because in some point we modify the
765 * structure, and I don't know why! --nmav
767 node = _asn1_copy_structure3( node);
768 if (node == NULL)
769 return ASN1_ELEMENT_NOT_FOUND;
771 max_len=*len;
773 counter=0;
774 move=DOWN;
775 p=node;
776 while(1){
778 counter_old=counter;
779 max_len_old=max_len;
780 if(move!=UP){
781 err = _asn1_insert_tag_der(p,der,&counter,&max_len);
782 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
783 goto error;
785 switch(type_field(p->type)){
786 case TYPE_NULL:
787 max_len--;
788 if(max_len>=0)
789 der[counter++]=0;
790 move=RIGHT;
791 break;
792 case TYPE_BOOLEAN:
793 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
794 counter=counter_old;
795 max_len=max_len_old;
797 else{
798 if(p->value==NULL){
799 _asn1_error_description_value_not_found(p,ErrorDescription);
800 err = ASN1_VALUE_NOT_FOUND;
801 goto error;
803 max_len -= 2;
804 if(max_len>=0){
805 der[counter++]=1;
806 if(p->value[0]=='F') der[counter++]=0;
807 else der[counter++]=0xFF;
809 else
810 counter+=2;
812 move=RIGHT;
813 break;
814 case TYPE_INTEGER: case TYPE_ENUMERATED:
815 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
816 counter=counter_old;
817 max_len=max_len_old;
819 else{
820 if(p->value==NULL){
821 _asn1_error_description_value_not_found(p,ErrorDescription);
822 err = ASN1_VALUE_NOT_FOUND;
823 goto error;
825 len2=asn1_get_length_der(p->value,p->value_len, &len3);
826 if (len2<0) {
827 err = ASN1_DER_ERROR;
828 goto error;
830 max_len -= len2+len3;
831 if(max_len>=0)
832 memcpy(der+counter,p->value,len3+len2);
833 counter+=len3+len2;
835 move=RIGHT;
836 break;
837 case TYPE_OBJECT_ID:
838 if((p->type&CONST_DEFAULT) && (p->value==NULL)){
839 counter=counter_old;
840 max_len=max_len_old;
842 else{
843 if(p->value==NULL){
844 _asn1_error_description_value_not_found(p,ErrorDescription);
845 err = ASN1_VALUE_NOT_FOUND;
846 goto error;
848 len2=max_len;
849 err = _asn1_objectid_der(p->value,der+counter,&len2);
850 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
851 goto error;
853 max_len-=len2;
854 counter+=len2;
856 move=RIGHT;
857 break;
858 case TYPE_TIME:
859 if(p->value==NULL){
860 _asn1_error_description_value_not_found(p,ErrorDescription);
861 err = ASN1_VALUE_NOT_FOUND;
862 goto error;
864 len2=max_len;
865 err = _asn1_time_der(p->value,der+counter,&len2);
866 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
867 goto error;
869 max_len-=len2;
870 counter+=len2;
871 move=RIGHT;
872 break;
873 case TYPE_OCTET_STRING:
874 if(p->value==NULL){
875 _asn1_error_description_value_not_found(p,ErrorDescription);
876 err = ASN1_VALUE_NOT_FOUND;
877 goto error;
879 len2=asn1_get_length_der(p->value,p->value_len,&len3);
880 if (len2<0) {
881 err = ASN1_DER_ERROR;
882 goto error;
884 max_len-=len2+len3;
885 if(max_len>=0)
886 memcpy(der+counter,p->value,len3+len2);
887 counter+=len3+len2;
888 move=RIGHT;
889 break;
890 case TYPE_GENERALSTRING:
891 if(p->value==NULL){
892 _asn1_error_description_value_not_found(p,ErrorDescription);
893 err = ASN1_VALUE_NOT_FOUND;
894 goto error;
896 len2=asn1_get_length_der(p->value,p->value_len,&len3);
897 if (len2<0) {
898 err = ASN1_DER_ERROR;
899 goto error;
901 max_len-=len2+len3;
902 if(max_len>=0)
903 memcpy(der+counter,p->value,len3+len2);
904 counter+=len3+len2;
905 move=RIGHT;
906 break;
907 case TYPE_BIT_STRING:
908 if(p->value==NULL){
909 _asn1_error_description_value_not_found(p,ErrorDescription);
910 err = ASN1_VALUE_NOT_FOUND;
911 goto error;
913 len2=asn1_get_length_der(p->value,p->value_len,&len3);
914 if (len2<0) {
915 err = ASN1_DER_ERROR;\
916 goto error;
918 max_len-=len2+len3;
919 if(max_len>=0)
920 memcpy(der+counter,p->value,len3+len2);
921 counter+=len3+len2;
922 move=RIGHT;
923 break;
924 case TYPE_SEQUENCE: case TYPE_SET:
925 if(move!=UP){
926 _asn1_ltostr(counter,temp);
927 tlen = strlen(temp);
928 if (tlen > 0)
929 _asn1_set_value(p,temp,tlen+1);
930 if(p->down==NULL){
931 move=UP;
932 continue;
934 else{
935 p2=p->down;
936 while(p2 && (type_field(p2->type)==TYPE_TAG)) p2=p2->right;
937 if(p2){
938 p=p2;
939 move=RIGHT;
940 continue;
942 move=UP;
943 continue;
946 else{ /* move==UP */
947 len2=strtol(p->value,NULL,10);
948 _asn1_set_value(p,NULL,0);
949 if((type_field(p->type)==TYPE_SET) && (max_len>=0))
950 _asn1_ordering_set(der+len2, max_len-len2,p);
951 asn1_length_der(counter-len2,temp,&len3);
952 max_len-=len3;
953 if(max_len>=0){
954 memmove(der+len2+len3,der+len2,counter-len2);
955 memcpy(der+len2,temp,len3);
957 counter+=len3;
958 move=RIGHT;
960 break;
961 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
962 if(move!=UP){
963 _asn1_ltostr(counter,temp);
964 tlen = strlen(temp);
966 if (tlen > 0)
967 _asn1_set_value(p,temp,tlen+1);
968 p=p->down;
969 while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right;
970 if(p->right){
971 p=p->right;
972 move=RIGHT;
973 continue;
975 else p=_asn1_find_up(p);
976 move=UP;
978 if(move==UP){
979 len2=strtol(p->value,NULL,10);
980 _asn1_set_value(p,NULL,0);
981 if((type_field(p->type)==TYPE_SET_OF) && (max_len-len2>0)) {
982 _asn1_ordering_set_of(der+len2, max_len-len2,p);
984 asn1_length_der(counter-len2,temp,&len3);
985 max_len-=len3;
986 if(max_len>=0){
987 memmove(der+len2+len3,der+len2,counter-len2);
988 memcpy(der+len2,temp,len3);
990 counter+=len3;
991 move=RIGHT;
993 break;
994 case TYPE_ANY:
995 if(p->value==NULL){
996 _asn1_error_description_value_not_found(p,ErrorDescription);
997 err = ASN1_VALUE_NOT_FOUND;
998 goto error;
1000 len2=asn1_get_length_der(p->value,p->value_len,&len3);
1001 if (len2<0) {
1002 err = ASN1_DER_ERROR;
1003 goto error;
1005 max_len-=len2;
1006 if(max_len>=0)
1007 memcpy(der+counter,p->value+len3,len2);
1008 counter+=len2;
1009 move=RIGHT;
1010 break;
1011 default:
1012 move=(move==UP)?RIGHT:DOWN;
1013 break;
1016 if((move!=DOWN) && (counter!=counter_old)){
1017 err=_asn1_complete_explicit_tag(p,der,&counter,&max_len);
1018 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1019 goto error;
1022 if(p==node && move!=DOWN) break;
1024 if(move==DOWN){
1025 if(p->down) p=p->down;
1026 else move=RIGHT;
1028 if(move==RIGHT){
1029 if(p->right) p=p->right;
1030 else move=UP;
1032 if(move==UP) p=_asn1_find_up(p);
1035 *len=counter;
1037 if(max_len<0) {
1038 err = ASN1_MEM_ERROR;
1039 goto error;
1042 err = ASN1_SUCCESS;
1044 error:
1045 asn1_delete_structure(&node);
1046 return err;