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 /*****************************************************/
24 /* Description: Functions to create a DER coding of */
26 /*****************************************************/
31 #include "parser_aux.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. */
42 /* node: node of the tree where the value is NULL. */
43 /* ErrorDescription: string returned. */
45 /******************************************************/
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). */
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]). */
69 /******************************************************/
71 _asn1_length_der(unsigned long len
,unsigned char *ans
,int *ans_len
)
74 unsigned char temp
[SIZEOF_UNSIGNED_LONG_INT
];
78 if(ans
!=NULL
) ans
[0]=(unsigned char)len
;
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. */
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]). */
107 /******************************************************/
109 _asn1_tag_der(unsigned char class,unsigned int tag_value
,unsigned char *ans
,int *ans_len
)
112 unsigned char temp
[SIZEOF_UNSIGNED_INT
];
116 ans
[0]=(class&0xE0) + ((unsigned char)(tag_value
&0x1F));
121 ans
[0]=(class&0xE0) + 31;
124 temp
[k
++]=tag_value
&0x7F;
125 tag_value
=tag_value
>>7;
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). */
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]). */
144 /******************************************************/
146 _asn1_octet_der(const unsigned char *str
,int str_len
,unsigned char *der
,int *der_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). */
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. */
167 /* ASN1_MEM_ERROR when DER isn't big enough */
168 /* ASN1_SUCCESS otherwise */
169 /******************************************************/
171 _asn1_time_der(unsigned char *str
,unsigned char *der
,int *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
;
192 _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
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;
204 strcat(temp,"00+0000");
208 strcat(temp,"+0000");
212 memmove(temp+12,temp+10,6);
213 temp[10]=temp[11]='0';
225 /******************************************************/
226 /* Function : _asn1_objectid_der */
227 /* Description: creates the DER coding for an */
228 /* OBJECT IDENTIFIER type (length included). */
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. */
236 /* ASN1_MEM_ERROR when DER isn't big enough */
237 /* ASN1_SUCCESS otherwise */
238 /******************************************************/
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
;
245 unsigned long val
,val1
=0;
247 if(der
==NULL
) return ASN1_SUCCESS
;
251 temp
=(char *) malloc(strlen(str
)+2);
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 meanful bits in STR. */
310 /* der: string returned. */
311 /* der_len: number of meanful 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 meanful 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 alla date 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 meanful 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 memmove(der
+counter
,der
+p_vet
->end
,p2_vet
->end
-p_vet
->end
);
597 memcpy(der
+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 memmove(der
+counter
,der
+p_vet
->end
,p2_vet
->end
-p_vet
->end
);
699 memcpy(der
+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 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.
726 * Creates the DER encoding for the NAME structure (inside *POINTER structure).
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.
741 asn1_der_coding(ASN1_TYPE element
,const char *name
,unsigned char *der
,int *len
,
742 char *ErrorDescription
)
745 char temp
[SIZEOF_UNSIGNED_LONG_INT
*3+1];
746 int counter
,counter_old
,len2
,len3
,move
,max_len
,max_len_old
;
749 node
=_asn1_find_node(element
,name
);
750 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
762 ris
=_asn1_insert_tag_der(p
,der
,&counter
,&max_len
);
764 switch(type_field(p
->type
)){
772 if((p
->type
&CONST_DEFAULT
) && (p
->value
==NULL
)){
778 _asn1_error_description_value_not_found(p
,ErrorDescription
);
779 return ASN1_VALUE_NOT_FOUND
;
784 if(p
->value
[0]=='F') der
[counter
++]=0;
785 else der
[counter
++]=0xFF;
790 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
791 if((p
->type
&CONST_DEFAULT
) && (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
;
803 memcpy(der
+counter
,p
->value
,len3
+len2
);
810 _asn1_error_description_value_not_found(p
,ErrorDescription
);
811 return ASN1_VALUE_NOT_FOUND
;
814 ris
=_asn1_objectid_der(p
->value
,der
+counter
,&len2
);
821 _asn1_error_description_value_not_found(p
,ErrorDescription
);
822 return ASN1_VALUE_NOT_FOUND
;
825 ris
=_asn1_time_der(p
->value
,der
+counter
,&len2
);
830 case TYPE_OCTET_STRING
:
832 _asn1_error_description_value_not_found(p
,ErrorDescription
);
833 return ASN1_VALUE_NOT_FOUND
;
835 len2
=_asn1_get_length_der(p
->value
,&len3
);
838 memcpy(der
+counter
,p
->value
,len3
+len2
);
842 case TYPE_GENERALSTRING
:
844 _asn1_error_description_value_not_found(p
,ErrorDescription
);
845 return ASN1_VALUE_NOT_FOUND
;
847 len2
=_asn1_get_length_der(p
->value
,&len3
);
850 memcpy(der
+counter
,p
->value
,len3
+len2
);
854 case TYPE_BIT_STRING
:
856 _asn1_error_description_value_not_found(p
,ErrorDescription
);
857 return ASN1_VALUE_NOT_FOUND
;
859 len2
=_asn1_get_length_der(p
->value
,&len3
);
862 memcpy(der
+counter
,p
->value
,len3
+len2
);
866 case TYPE_SEQUENCE
: case TYPE_SET
:
868 _asn1_ltostr(counter
,temp
);
869 _asn1_set_value(p
,temp
,strlen(temp
)+1);
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
);
880 memmove(der
+len2
+len3
,der
+len2
,counter
-len2
);
881 memcpy(der
+len2
,temp
,len3
);
887 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
889 _asn1_ltostr(counter
,temp
);
890 _asn1_set_value(p
,temp
,strlen(temp
)+1);
892 while((type_field(p
->type
)==TYPE_TAG
) || (type_field(p
->type
)==TYPE_SIZE
)) p
=p
->right
;
898 else p
=_asn1_find_up(p
);
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
);
909 memmove(der
+len2
+len3
,der
+len2
,counter
-len2
);
910 memcpy(der
+len2
,temp
,len3
);
918 _asn1_error_description_value_not_found(p
,ErrorDescription
);
919 return ASN1_VALUE_NOT_FOUND
;
921 len2
=_asn1_get_length_der(p
->value
,&len3
);
924 memcpy(der
+counter
,p
->value
+len3
,len2
);
929 move
=(move
==UP
)?RIGHT
:DOWN
;
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;
940 if(p
->down
) p
=p
->down
;
944 if(p
->right
) p
=p
->right
;
947 if(move
==UP
) p
=_asn1_find_up(p
);
952 if(max_len
<0) return ASN1_MEM_ERROR
;