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: decoding.c */
24 /* Description: Functions to manage DER decoding */
25 /*****************************************************/
30 #include "parser_aux.h"
32 #include "structure.h"
37 _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
40 Estrcpy(ErrorDescription,":: tag error near element '");
41 _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
42 MAX_ERROR_DESCRIPTION_SIZE-40);
43 Estrcat(ErrorDescription,"'");
49 _asn1_get_length_der(const unsigned char *der,int *len)
63 if(k){ /* definite length method */
65 while(punt<=k) ans=ans*256+der[punt++];
67 else{ /* indefinite length method */
80 _asn1_get_tag_der(const unsigned char *der,unsigned char *class,int *len)
84 if (der==NULL || len == NULL) return ASN1_DER_ERROR;
86 if((der[0]&0x1F)!=0x1F){
95 while(der[punt]&128) ris=ris*128+(der[punt++]&0x7F);
96 ris=ris*128+(der[punt++]&0x7F);
106 _asn1_get_octet_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len)
110 /* if(str==NULL) return ASN1_SUCCESS; */
111 *str_len=_asn1_get_length_der(der,&len_len);
113 *der_len=*str_len+len_len;
114 if ( str_size >= *str_len)
115 memcpy(str,der+len_len,*str_len);
117 return ASN1_MEM_ERROR;
125 /* Returns ASN1_SUCCESS on success or an error code on error.
128 _asn1_get_time_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size)
132 if(str==NULL) return ASN1_DER_ERROR;
133 str_len=_asn1_get_length_der(der,&len_len);
134 if (str_len < 0 || str_size < str_len)
135 return ASN1_DER_ERROR;
136 memcpy(str,der+len_len,str_len);
138 *der_len=str_len+len_len;
146 _asn1_get_objectid_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size)
150 unsigned long val,val1;
152 if(str==NULL) return;
153 len=_asn1_get_length_der(der,&len_len);
155 val1=der[len_len]/40;
156 val=der[len_len]-val1*40;
158 _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
159 _asn1_str_cat(str, str_size, ".");
160 _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
165 val|=der[len_len+k]&0x7F;
166 if(!(der[len_len+k]&0x80)){
167 _asn1_str_cat(str, str_size,".");
168 _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
172 *der_len=len+len_len;
179 _asn1_get_bit_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len)
181 int len_len,len_byte;
183 len_byte=_asn1_get_length_der(der,&len_len)-1;
185 *der_len=len_byte+len_len+1;
186 *bit_len=len_byte*8-der[len_len];
188 if (str_size >= len_byte)
189 memcpy(str,der+len_len+1,len_byte);
191 return ASN1_MEM_ERROR;
201 _asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len)
204 int counter,len2,len3,is_tag_implicit;
205 unsigned long tag,tag_implicit=0;
206 unsigned char class,class2,class_implicit=0;
209 counter=is_tag_implicit=0;
211 if(node->type&CONST_TAG){
214 if(type_field(p->type)==TYPE_TAG){
215 if(p->type&CONST_APPLICATION) class2=APPLICATION;
216 else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
217 else if(p->type&CONST_PRIVATE) class2=PRIVATE;
218 else class2=CONTEXT_SPECIFIC;
220 if(p->type&CONST_EXPLICIT){
221 tag=_asn1_get_tag_der(der+counter,&class,&len2);
223 len3=_asn1_get_length_der(der+counter,&len2);
225 if(!is_tag_implicit){
226 if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
227 return ASN1_TAG_ERROR;
229 else{ /* TAG_IMPLICIT */
230 if((class!=class_implicit) || (tag!=tag_implicit))
231 return ASN1_TAG_ERROR;
236 else{ /* TAG_IMPLICIT */
237 if(!is_tag_implicit){
238 if((type_field(node->type)==TYPE_SEQUENCE) ||
239 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
240 (type_field(node->type)==TYPE_SET) ||
241 (type_field(node->type)==TYPE_SET_OF)) class2|=STRUCTURED;
242 class_implicit=class2;
243 tag_implicit=strtoul(p->value,NULL,10);
253 tag=_asn1_get_tag_der(der+counter,&class,&len2);
254 if((class!=class_implicit) || (tag!=tag_implicit)){
255 if(type_field(node->type)==TYPE_OCTET_STRING){
256 class_implicit |= STRUCTURED;
257 if((class!=class_implicit) || (tag!=tag_implicit))
258 return ASN1_TAG_ERROR;
261 return ASN1_TAG_ERROR;
265 if(type_field(node->type)==TYPE_TAG){
271 tag=_asn1_get_tag_der(der+counter,&class,&len2);
272 switch(type_field(node->type)){
274 if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
277 if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
280 if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
282 case TYPE_ENUMERATED:
283 if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
286 if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
289 if(node->type&CONST_UTC){
290 if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
293 if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime))
294 return ASN1_DER_ERROR;
297 case TYPE_OCTET_STRING:
298 if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
299 || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
301 case TYPE_GENERALSTRING:
302 if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
304 case TYPE_BIT_STRING:
305 if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
307 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
308 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE))
309 return ASN1_DER_ERROR;
311 case TYPE_SET: case TYPE_SET_OF:
312 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET))
313 return ASN1_DER_ERROR;
319 return ASN1_DER_ERROR;
331 _asn1_delete_not_used(node_asn *node)
335 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
339 if(p->type&CONST_NOT_USED){
342 p2=_asn1_find_left(p);
343 if(!p2) p2=_asn1_find_up(p);
345 asn1_delete_structure(&p);
349 if(!p) break; /* reach node */
356 else if(p->right) p=p->right;
377 _asn1_get_octet_string(const unsigned char* der,node_asn *node,int* len)
379 int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
384 if(*(der-1) & STRUCTURED){
386 indefinite=_asn1_get_length_der(der,&len3);
389 if(indefinite>=0) indefinite+=len3;
392 if(counter>(*len)) return ASN1_DER_ERROR;
395 if((der[counter]==0) && (der[counter+1]==0)){
400 else if(counter>=indefinite) break;
402 if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
406 len2=_asn1_get_length_der(der+counter,&len3);
407 if(len2 <= 0) return ASN1_DER_ERROR;
415 _asn1_length_der(tot_len,NULL,&len2);
416 temp=(unsigned char *)_asn1_alloca(len2+tot_len);
418 return ASN1_MEM_ALLOC_ERROR;
421 _asn1_length_der(tot_len,temp,&len2);
424 len2=_asn1_get_length_der(der,&len3);
427 if(indefinite==-1) counter_end=counter-2;
428 else counter_end=counter;
430 while(counter2<counter_end){
431 len2=_asn1_get_length_der(der+counter2,&len3);
432 memcpy(temp2,der+counter2+len3,len2);
434 counter2+=len2+len3+1;
436 _asn1_set_value(node,temp,tot_len);
440 else{ /* NOT STRUCTURED */
441 len2=_asn1_get_length_der(der,&len3);
443 _asn1_set_value(node,der,len3+len2);
454 _asn1_get_indefinite_length_string(const unsigned char* der,int* len)
456 int len2,len3,counter,indefinite;
460 counter=indefinite=0;
463 if((*len)<counter) return ASN1_DER_ERROR;
465 if((der[counter]==0) && (der[counter+1]==0)){
468 if(indefinite<=0) break;
472 tag=_asn1_get_tag_der(der+counter,&class,&len2);
474 len2=_asn1_get_length_der(der+counter,&len3);
491 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
492 * @element: pointer to an ASN1 structure
493 * @ider: vector that contains the DER encoding.
494 * @len: number of bytes of *der: der[0]..der[len-1]
497 * Fill the structure *ELEMENT with values of a DER encoding string. The sructure must just be
498 * created with function 'create_stucture'.
499 * If an error occurs during the decoding procedure, the *ELEMENT is deleted
500 * and set equal to ASN1_TYPE_EMPTY.
504 * ASN1_SUCCESS\: DER encoding OK
506 * ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY.
508 * ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure NAME. *ELEMENT deleted.
512 asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
513 char *errorDescription)
515 node_asn *node,*p,*p2,*p3;
517 int counter,len2,len3,len4,move,ris;
518 unsigned char class,*temp2;
520 int indefinite, result;
521 const unsigned char* der = ider;
525 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
527 if(node->type&CONST_OPTION){
528 asn1_delete_structure(element);
529 return ASN1_GENERIC_ERROR;
538 if(p->type&CONST_SET){
540 len2=strtol(p2->value,NULL,10);
542 if(!der[counter] && !der[counter+1]){
549 else if(counter==len2){
554 else if(counter>len2){
555 asn1_delete_structure(element);
556 return ASN1_DER_ERROR;
560 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
561 if(type_field(p2->type)!=TYPE_CHOICE)
562 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
566 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
567 if(ris==ASN1_SUCCESS) break;
571 if(ris==ASN1_SUCCESS){
572 p2->type&=~CONST_NOT_USED;
580 asn1_delete_structure(element);
581 return ASN1_DER_ERROR;
585 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
587 len2=strtol(p2->value,NULL,10);
595 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
602 if(type_field(p->type)==TYPE_CHOICE){
605 ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
608 if(ris==ASN1_SUCCESS){
609 while(p->down->right){
611 asn1_delete_structure(&p2);
615 else if(ris==ASN1_ERROR_TYPE_ANY){
616 asn1_delete_structure(element);
617 return ASN1_ERROR_TYPE_ANY;
621 asn1_delete_structure(&p2);
626 if(!(p->type&CONST_OPTION)){
627 asn1_delete_structure(element);
628 return ASN1_DER_ERROR;
635 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
637 len2=strtol(p2->value,NULL,10);
638 if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
641 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
642 if(ris!=ASN1_SUCCESS){
643 if(p->type&CONST_OPTION){
644 p->type|=CONST_NOT_USED;
647 else if(p->type&CONST_DEFAULT) {
648 _asn1_set_value(p,NULL,0);
652 if (errorDescription!=NULL)
653 _asn1_error_description_tag_error(p,errorDescription);
655 asn1_delete_structure(element);
656 return ASN1_TAG_ERROR;
662 if(ris==ASN1_SUCCESS){
663 switch(type_field(p->type)){
666 asn1_delete_structure(element);
667 return ASN1_DER_ERROR;
673 if(der[counter++]!=1){
674 asn1_delete_structure(element);
675 return ASN1_DER_ERROR;
677 if(der[counter++]==0) _asn1_set_value(p,"F",1);
678 else _asn1_set_value(p,"T",1);
681 case TYPE_INTEGER: case TYPE_ENUMERATED:
682 len2=_asn1_get_length_der(der+counter,&len3);
683 _asn1_set_value(p,der+counter,len3+len2);
688 _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
689 _asn1_set_value(p,temp,strlen(temp)+1);
694 result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1);
695 if (result != ASN1_SUCCESS) {
696 asn1_delete_structure(element);
699 _asn1_set_value(p,temp,strlen(temp)+1);
703 case TYPE_OCTET_STRING:
705 ris=_asn1_get_octet_string(der+counter,p,&len3);
706 if(ris != ASN1_SUCCESS) return ris;
710 case TYPE_GENERALSTRING:
711 len2=_asn1_get_length_der(der+counter,&len3);
712 _asn1_set_value(p,der+counter,len3+len2);
716 case TYPE_BIT_STRING:
717 len2=_asn1_get_length_der(der+counter,&len3);
718 _asn1_set_value(p,der+counter,len3+len2);
722 case TYPE_SEQUENCE: case TYPE_SET:
724 len2=strtol(p->value,NULL,10);
725 _asn1_set_value(p,NULL,0);
726 if(len2==-1){ /* indefinite length method */
727 if((der[counter]) || der[counter+1]){
728 asn1_delete_structure(element);
729 return ASN1_DER_ERROR;
733 else{ /* definite length method */
735 asn1_delete_structure(element);
736 return ASN1_DER_ERROR;
741 else{ /* move==DOWN || move==RIGHT */
742 len3=_asn1_get_length_der(der+counter,&len2);
745 _asn1_ltostr(counter+len3,temp);
746 _asn1_set_value(p,temp,strlen(temp)+1);
752 if(type_field(p2->type)!=TYPE_TAG){
754 asn1_delete_structure(&p2);
762 else{ /* indefinite length method */
763 _asn1_set_value(p,"-1",3);
768 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
770 len2=strtol(p->value,NULL,10);
771 if(len2==-1){ /* indefinite length method */
772 if((counter+2)>len) return ASN1_DER_ERROR;
773 if((der[counter]) || der[counter+1]){
774 _asn1_append_sequence_set(p);
776 while(p->right) p=p->right;
780 _asn1_set_value(p,NULL,0);
783 else{ /* definite length method */
785 _asn1_append_sequence_set(p);
787 while(p->right) p=p->right;
791 _asn1_set_value(p,NULL,0);
793 asn1_delete_structure(element);
794 return ASN1_DER_ERROR;
798 else{ /* move==DOWN || move==RIGHT */
799 len3=_asn1_get_length_der(der+counter,&len2);
802 if(len3>0){ /* definite length method */
803 _asn1_ltostr(counter+len3,temp);
804 _asn1_set_value(p,temp,strlen(temp)+1);
806 else { /* indefinite length method */
807 _asn1_set_value(p,"-1",3);
810 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
811 if(p2->right==NULL) _asn1_append_sequence_set(p);
818 tag=_asn1_get_tag_der(der+counter,&class,&len2);
819 len4=_asn1_get_length_der(der+counter+len2,&len3);
823 _asn1_length_der(len2+len3,NULL,&len4);
824 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
826 asn1_delete_structure(element);
827 return ASN1_MEM_ALLOC_ERROR;
830 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
831 _asn1_set_value(p,temp2,len4);
835 else{ /* indefinite length */
836 /* Check indefinite lenth method in an EXPLICIT TAG */
837 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
843 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
844 if(ris != ASN1_SUCCESS){
845 asn1_delete_structure(element);
848 _asn1_length_der(len2,NULL,&len4);
849 temp2=(unsigned char *)_asn1_alloca(len2+len4);
851 asn1_delete_structure(element);
852 return ASN1_MEM_ALLOC_ERROR;
855 _asn1_octet_der(der+counter,len2,temp2,&len4);
856 _asn1_set_value(p,temp2,len4);
860 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
861 an indefinite length method. */
863 if(!der[counter] && !der[counter+1]){
867 asn1_delete_structure(element);
868 return ASN1_DER_ERROR;
875 move=(move==UP)?RIGHT:DOWN;
880 if(p==node && move!=DOWN) break;
883 if(p->down) p=p->down;
886 if((move==RIGHT) && !(p->type&CONST_SET)){
887 if(p->right) p=p->right;
890 if(move==UP) p=_asn1_find_up(p);
893 _asn1_delete_not_used(*element);
896 asn1_delete_structure(element);
897 return ASN1_DER_ERROR;
905 #define SAME_BRANCH 2
906 #define OTHER_BRANCH 3
910 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
911 * @structure: pointer to an ASN1 structure
912 * @elementName: name of the element to fill
913 * @ider: vector that contains the DER encoding of the whole structure.
914 * @len: number of bytes of *der: der[0]..der[len-1]
915 * @errorDescription: null-terminated string contains details when an error occurred.
919 * Fill the element named ELEMENTNAME with values of a DER encoding string.
920 * The sructure must just be created with function 'create_stucture'.
921 * The DER vector must contain the encoding string of the whole STRUCTURE.
922 * If an error occurs during the decoding procedure, the *STRUCTURE is deleted
923 * and set equal to ASN1_TYPE_EMPTY.
927 * ASN1_SUCCESS\: DER encoding OK
929 * ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY or elementName == NULL.
931 * ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure STRUCTURE. *ELEMENT deleted.
935 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
936 const void *ider,int len,char *errorDescription)
938 node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
939 char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
940 int nameLen=MAX_NAME_SIZE*10-1,state;
941 int counter,len2,len3,len4,move,ris;
942 unsigned char class,*temp2;
944 int indefinite, result;
945 const unsigned char* der = ider;
949 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
951 if(elementName == NULL){
952 asn1_delete_structure(structure);
953 return ASN1_ELEMENT_NOT_FOUND;
956 if(node->type&CONST_OPTION){
957 asn1_delete_structure(structure);
958 return ASN1_GENERIC_ERROR;
961 if((*structure)->name){ /* Has *structure got a name? */
962 nameLen-=strlen((*structure)->name);
963 if(nameLen>0) strcpy(currentName,(*structure)->name);
965 asn1_delete_structure(structure);
966 return ASN1_MEM_ERROR;
968 if(!(strcmp(currentName,elementName))){
970 nodeFound=*structure;
972 else if(!memcmp(currentName,elementName,strlen(currentName)))
977 else{ /* *structure doesn't have a name? */
979 if(elementName[0]==0){
981 nodeFound=*structure;
996 if(p->type&CONST_SET){
998 len2=strtol(p2->value,NULL,10);
1004 else if(counter>len2){
1005 asn1_delete_structure(structure);
1006 return ASN1_DER_ERROR;
1010 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
1011 if(type_field(p2->type)!=TYPE_CHOICE)
1012 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1016 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1017 if(ris==ASN1_SUCCESS) break;
1021 if(ris==ASN1_SUCCESS){
1022 p2->type&=~CONST_NOT_USED;
1030 asn1_delete_structure(structure);
1031 return ASN1_DER_ERROR;
1035 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1036 p2=_asn1_find_up(p);
1037 len2=strtol(p2->value,NULL,10);
1045 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
1052 if(type_field(p->type)==TYPE_CHOICE){
1055 ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
1058 if(ris==ASN1_SUCCESS){
1059 while(p->down->right){
1061 asn1_delete_structure(&p2);
1065 else if(ris==ASN1_ERROR_TYPE_ANY){
1066 asn1_delete_structure(structure);
1067 return ASN1_ERROR_TYPE_ANY;
1071 asn1_delete_structure(&p2);
1076 if(!(p->type&CONST_OPTION)){
1077 asn1_delete_structure(structure);
1078 return ASN1_DER_ERROR;
1085 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1086 p2=_asn1_find_up(p);
1087 len2=strtol(p2->value,NULL,10);
1088 if(counter>len2) ris=ASN1_TAG_ERROR;
1091 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1092 if(ris!=ASN1_SUCCESS){
1093 if(p->type&CONST_OPTION){
1094 p->type|=CONST_NOT_USED;
1097 else if(p->type&CONST_DEFAULT) {
1098 _asn1_set_value(p,NULL,0);
1102 if (errorDescription!=NULL)
1103 _asn1_error_description_tag_error(p,errorDescription);
1105 asn1_delete_structure(structure);
1106 return ASN1_TAG_ERROR;
1112 if(ris==ASN1_SUCCESS){
1113 switch(type_field(p->type)){
1116 asn1_delete_structure(structure);
1117 return ASN1_DER_ERROR;
1120 if(p==nodeFound) state=EXIT;
1126 if(der[counter++]!=1){
1127 asn1_delete_structure(structure);
1128 return ASN1_DER_ERROR;
1132 if(der[counter++]==0) _asn1_set_value(p,"F",1);
1133 else _asn1_set_value(p,"T",1);
1135 if(p==nodeFound) state=EXIT;
1143 case TYPE_INTEGER: case TYPE_ENUMERATED:
1144 len2=_asn1_get_length_der(der+counter,&len3);
1146 _asn1_set_value(p,der+counter,len3+len2);
1148 if(p==nodeFound) state=EXIT;
1153 case TYPE_OBJECT_ID:
1155 _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
1156 _asn1_set_value(p,temp,strlen(temp)+1);
1158 if(p==nodeFound) state=EXIT;
1161 len2=_asn1_get_length_der(der+counter,&len3);
1170 result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1);
1171 if (result != ASN1_SUCCESS) {
1172 asn1_delete_structure(structure);
1176 _asn1_set_value(p,temp,strlen(temp)+1);
1178 if(p==nodeFound) state=EXIT;
1181 len2=_asn1_get_length_der(der+counter,&len3);
1188 case TYPE_OCTET_STRING:
1191 ris=_asn1_get_octet_string(der+counter,p,&len3);
1192 if(p==nodeFound) state=EXIT;
1195 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1197 if(ris != ASN1_SUCCESS) return ris;
1201 case TYPE_GENERALSTRING:
1202 len2=_asn1_get_length_der(der+counter,&len3);
1204 _asn1_set_value(p,der+counter,len3+len2);
1206 if(p==nodeFound) state=EXIT;
1211 case TYPE_BIT_STRING:
1212 len2=_asn1_get_length_der(der+counter,&len3);
1214 _asn1_set_value(p,der+counter,len3+len2);
1216 if(p==nodeFound) state=EXIT;
1221 case TYPE_SEQUENCE: case TYPE_SET:
1223 len2=strtol(p->value,NULL,10);
1224 _asn1_set_value(p,NULL,0);
1225 if(len2==-1){ /* indefinite length method */
1226 if((der[counter]) || der[counter+1]){
1227 asn1_delete_structure(structure);
1228 return ASN1_DER_ERROR;
1232 else{ /* definite length method */
1234 asn1_delete_structure(structure);
1235 return ASN1_DER_ERROR;
1238 if(p==nodeFound) state=EXIT;
1241 else{ /* move==DOWN || move==RIGHT */
1242 if(state==OTHER_BRANCH){
1243 len3=_asn1_get_length_der(der+counter,&len2);
1247 else { /* state==SAME_BRANCH or state==FOUND */
1248 len3=_asn1_get_length_der(der+counter,&len2);
1251 _asn1_ltostr(counter+len3,temp);
1252 _asn1_set_value(p,temp,strlen(temp)+1);
1258 if(type_field(p2->type)!=TYPE_TAG){
1260 asn1_delete_structure(&p2);
1268 else{ /* indefinite length method */
1269 _asn1_set_value(p,"-1",3);
1275 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1277 len2=strtol(p->value,NULL,10);
1279 _asn1_append_sequence_set(p);
1281 while(p->right) p=p->right;
1285 _asn1_set_value(p,NULL,0);
1287 asn1_delete_structure(structure);
1288 return ASN1_DER_ERROR;
1291 if(p==nodeFound) state=EXIT;
1293 else{ /* move==DOWN || move==RIGHT */
1294 if(state==OTHER_BRANCH){
1295 len3=_asn1_get_length_der(der+counter,&len2);
1299 else{ /* state==FOUND or state==SAME_BRANCH */
1300 len3=_asn1_get_length_der(der+counter,&len2);
1303 _asn1_ltostr(counter+len3,temp);
1304 _asn1_set_value(p,temp,strlen(temp)+1);
1306 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1307 if(p2->right==NULL) _asn1_append_sequence_set(p);
1316 tag=_asn1_get_tag_der(der+counter,&class,&len2);
1317 len4=_asn1_get_length_der(der+counter+len2,&len3);
1322 _asn1_length_der(len2+len3,NULL,&len4);
1323 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
1325 asn1_delete_structure(structure);
1326 return ASN1_MEM_ALLOC_ERROR;
1329 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
1330 _asn1_set_value(p,temp2,len4);
1333 if(p==nodeFound) state=EXIT;
1337 else{ /* indefinite length */
1338 /* Check indefinite lenth method in an EXPLICIT TAG */
1339 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1345 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1346 if(ris != ASN1_SUCCESS){
1347 asn1_delete_structure(structure);
1352 _asn1_length_der(len2,NULL,&len4);
1353 temp2=(unsigned char *)_asn1_alloca(len2+len4);
1355 asn1_delete_structure(structure);
1356 return ASN1_MEM_ALLOC_ERROR;
1359 _asn1_octet_der(der+counter,len2,temp2,&len4);
1360 _asn1_set_value(p,temp2,len4);
1363 if(p==nodeFound) state=EXIT;
1368 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1369 an indefinite length method. */
1371 if(!der[counter] && !der[counter+1]){
1375 asn1_delete_structure(structure);
1376 return ASN1_DER_ERROR;
1384 move=(move==UP)?RIGHT:DOWN;
1389 if((p==node && move!=DOWN) || (state==EXIT)) break;
1396 nameLen-=strlen(p->name)+1;
1398 if(currentName[0]) strcat(currentName,".");
1399 strcat(currentName,p->name);
1402 asn1_delete_structure(structure);
1403 return ASN1_MEM_ERROR;
1405 if(!(strcmp(currentName,elementName))){
1409 else if(!memcmp(currentName,elementName,strlen(currentName)))
1418 if((move==RIGHT) && !(p->type&CONST_SET)){
1423 dot_p=char_p=currentName;
1424 while((char_p=strchr(char_p,'.'))){
1429 nameLen+=strlen(currentName)-(dot_p-currentName);
1432 nameLen-=strlen(p->name);
1433 if(nameLen>0) strcat(currentName,p->name);
1435 asn1_delete_structure(structure);
1436 return ASN1_MEM_ERROR;
1439 if(!(strcmp(currentName,elementName))){
1443 else if(!memcmp(currentName,elementName,strlen(currentName)))
1456 dot_p=char_p=currentName;
1457 while((char_p=strchr(char_p,'.'))){
1462 nameLen+=strlen(currentName)-(dot_p-currentName);
1465 if(!(strcmp(currentName,elementName))){
1469 else if(!memcmp(currentName,elementName,strlen(currentName)))
1477 _asn1_delete_not_used(*structure);
1480 asn1_delete_structure(structure);
1481 return ASN1_DER_ERROR;
1484 return ASN1_SUCCESS;
1490 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1491 * @element: pointer to an ASN1 element
1492 * @ider: vector that contains the DER encoding.
1493 * @len: number of bytes of *der: der[0]..der[len-1]
1494 * @name_element: an element of NAME structure.
1495 * @start: the position of the first byte of NAME_ELEMENT decoding (der[*start])
1496 * @end: the position of the last byte of NAME_ELEMENT decoding (der[*end])
1499 * Find the start and end point of an element in a DER encoding string. I mean that if you
1500 * have a der encoding and you have already used the function "asn1_der_decoding" to fill a structure, it may
1501 * happen that you want to find the piece of string concerning an element of the structure.
1503 * Example: the sequence "tbsCertificate" inside an X509 certificate.
1507 * ASN1_SUCCESS\: DER encoding OK
1509 * ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE EMPTY or NAME_ELEMENT is not a valid element.
1511 * ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure ELEMENT.
1515 asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
1516 const char *name_element,int *start, int *end)
1518 node_asn *node,*node_to_find,*p,*p2,*p3;
1519 int counter,len2,len3,len4,move,ris;
1520 unsigned char class;
1523 const unsigned char* der = ider;
1527 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1529 node_to_find=_asn1_find_node(node,name_element);
1531 if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
1533 if(node_to_find==node){
1536 return ASN1_SUCCESS;
1539 if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
1548 if(p->type&CONST_SET){
1549 p2=_asn1_find_up(p);
1550 len2=strtol(p2->value,NULL,10);
1552 if(!der[counter] && !der[counter+1]){
1559 else if(counter==len2){
1564 else if(counter>len2) return ASN1_DER_ERROR;
1567 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
1568 if(type_field(p2->type)!=TYPE_CHOICE)
1569 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1572 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1574 if(ris==ASN1_SUCCESS){
1575 p2->type&=~CONST_NOT_USED;
1582 if(p2==NULL) return ASN1_DER_ERROR;
1585 if(p==node_to_find) *start=counter;
1587 if(type_field(p->type)==TYPE_CHOICE){
1589 ris=_asn1_extract_tag_der(p,der+counter,&len2);
1590 if(p==node_to_find) *start=counter;
1593 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1594 if(ris!=ASN1_SUCCESS){
1595 if(p->type&CONST_OPTION){
1596 p->type|=CONST_NOT_USED;
1599 else if(p->type&CONST_DEFAULT) {
1603 return ASN1_TAG_ERROR;
1609 if(ris==ASN1_SUCCESS){
1610 switch(type_field(p->type)){
1612 if(der[counter]) return ASN1_DER_ERROR;
1617 if(der[counter++]!=1) return ASN1_DER_ERROR;
1621 case TYPE_INTEGER: case TYPE_ENUMERATED:
1622 len2=_asn1_get_length_der(der+counter,&len3);
1626 case TYPE_OBJECT_ID:
1627 len2=_asn1_get_length_der(der+counter,&len3);
1632 len2=_asn1_get_length_der(der+counter,&len3);
1636 case TYPE_OCTET_STRING:
1638 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1639 if(ris != ASN1_SUCCESS) return ris;
1643 case TYPE_GENERALSTRING:
1644 len2=_asn1_get_length_der(der+counter,&len3);
1648 case TYPE_BIT_STRING:
1649 len2=_asn1_get_length_der(der+counter,&len3);
1653 case TYPE_SEQUENCE: case TYPE_SET:
1655 len3=_asn1_get_length_der(der+counter,&len2);
1657 if(len3==0) move=RIGHT;
1661 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1666 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1668 len3=_asn1_get_length_der(der+counter,&len2);
1670 if((len3==-1) && !der[counter] && !der[counter+1])
1674 while((type_field(p2->type)==TYPE_TAG) ||
1675 (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1680 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1686 tag=_asn1_get_tag_der(der+counter,&class,&len2);
1687 len4=_asn1_get_length_der(der+counter+len2,&len3);
1690 counter+=len2+len4+len3;
1692 else{ /* indefinite length */
1693 /* Check indefinite lenth method in an EXPLICIT TAG */
1694 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1700 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1701 if(ris != ASN1_SUCCESS)
1705 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1706 an indefinite length method. */
1708 if(!der[counter] && !der[counter+1])
1711 return ASN1_DER_ERROR;
1717 move=(move==UP)?RIGHT:DOWN;
1722 if((p==node_to_find) && (move==RIGHT)){
1724 return ASN1_SUCCESS;
1727 if(p==node && move!=DOWN) break;
1730 if(p->down) p=p->down;
1733 if((move==RIGHT) && !(p->type&CONST_SET)){
1734 if(p->right) p=p->right;
1737 if(move==UP) p=_asn1_find_up(p);
1740 return ASN1_ELEMENT_NOT_FOUND;
1745 * asn1_expand_any_defined_by - Expand every "ANY DEFINED BY" fields of
1746 * structure *ELEMENT with the corresponding type.
1747 * @definitions: ASN1 definitions
1748 * @element: pointer to an ASN1 structure
1751 * Expands every "ANY DEFINED BY" element of a structure created from
1752 * a DER decoding process (asn1_der_decoding function). The element ANY
1753 * must be defined by an OBJECT IDENTIFIER. The type used to expand
1754 * the element ANY is the first one following the definition of
1755 * the actual value of the OBJECT IDENTIFIER.
1760 * ASN1_SUCCESS\: substitution OK
1762 * ASN1_ERROR_TYPE_ANY\: some "ANY DEFINED BY" element couldn't be expanded
1763 * due to a problem in OBJECT_ID -> TYPE association.
1764 * other errors\: result of der decoding process.
1768 asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
1770 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1771 asn1_retCode retCode=ASN1_SUCCESS,result;
1773 ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
1774 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1776 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1777 return ASN1_ELEMENT_NOT_FOUND;
1779 strcpy(definitionsName,definitions->name);
1780 strcat(definitionsName,".");
1785 switch(type_field(p->type)){
1787 if((p->type&CONST_DEFINED_BY) && (p->value)){
1788 /* search the "DEF_BY" element */
1790 while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
1794 retCode=ASN1_ERROR_TYPE_ANY;
1798 p3=_asn1_find_up(p);
1801 retCode=ASN1_ERROR_TYPE_ANY;
1807 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1811 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1814 p3=_asn1_find_up(p);
1815 p3=_asn1_find_up(p3);
1818 retCode=ASN1_ERROR_TYPE_ANY;
1825 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1829 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1831 retCode=ASN1_ERROR_TYPE_ANY;
1836 /* search the OBJECT_ID into definitions */
1837 p2=definitions->down;
1839 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
1840 (p2->type & CONST_ASSIGN)){
1841 strcpy(name,definitionsName);
1842 strcat(name,p2->name);
1845 result=asn1_read_value(definitions,name,value,&len);
1847 if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
1848 p2=p2->right; /* pointer to the structure to
1849 use for expansion */
1850 while((p2) && (p2->type & CONST_ASSIGN))
1854 strcpy(name,definitionsName);
1855 strcat(name,p2->name);
1857 result=asn1_create_element(definitions,name,&aux);
1858 if(result == ASN1_SUCCESS){
1859 _asn1_set_name(aux,p->name);
1860 len2=_asn1_get_length_der(p->value,&len3);
1862 result=asn1_der_decoding(&aux,p->value+len3,len2,
1864 if(result == ASN1_SUCCESS){
1866 _asn1_set_right(aux,p->right);
1867 _asn1_set_right(p,aux);
1869 result=asn1_delete_structure(&p);
1870 if(result == ASN1_SUCCESS){
1872 aux=ASN1_TYPE_EMPTY;
1875 else{ /* error with asn1_delete_structure */
1876 asn1_delete_structure(&aux);
1881 else{/* error with asn1_der_decoding */
1886 else{/* error with asn1_create_element */
1891 else{/* error with the pointer to the structure to exapand */
1892 retCode=ASN1_ERROR_TYPE_ANY;
1901 retCode=ASN1_ERROR_TYPE_ANY;
1915 else if(p==*element){
1919 else if(p->right) p=p->right;
1941 * asn1_expand_octet_string - Expand an "OCTET STRING" fields of
1942 * structure *ELEMENT with the corresponding type.
1943 * @definitions: ASN1 definitions
1944 * @element: pointer to an ASN1 structure
1945 * @octetName: name of the OCTECT STRING field to expand.
1946 * @objectName: name of the OBJECT IDENTIFIER field to use to define
1947 * the type for expansion.
1951 * Expands an "OCTET STRING" element of a structure created from
1952 * a DER decoding process (asn1_der_decoding function). The type used
1953 * for expansion is the first one following the definition of
1954 * the actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
1958 * ASN1_SUCCESS\: substitution OK
1960 * ASN1_ELEMENT_NOT_FOUND\: OBJECTNAME or OCTETNAME are not correct.
1962 * ASN1_VALUE_NOT_VALID\: wasn't possible to find the type to use
1965 * other errors\: result of der decoding process.
1968 asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
1969 const char *octetName,const char *objectName)
1971 char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1972 asn1_retCode retCode=ASN1_SUCCESS,result;
1974 ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
1975 ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
1976 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1978 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1979 return ASN1_ELEMENT_NOT_FOUND;
1981 octetNode=_asn1_find_node(*element,octetName);
1982 if(octetNode==ASN1_TYPE_EMPTY)
1983 return ASN1_ELEMENT_NOT_FOUND;
1984 if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
1985 return ASN1_ELEMENT_NOT_FOUND;
1986 if(octetNode->value==NULL)
1987 return ASN1_VALUE_NOT_FOUND;
1989 objectNode=_asn1_find_node(*element,objectName);
1990 if(objectNode==ASN1_TYPE_EMPTY)
1991 return ASN1_ELEMENT_NOT_FOUND;
1993 if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
1994 return ASN1_ELEMENT_NOT_FOUND;
1996 if(objectNode->value==NULL)
1997 return ASN1_VALUE_NOT_FOUND;
2000 /* search the OBJECT_ID into definitions */
2001 p2=definitions->down;
2003 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
2004 (p2->type & CONST_ASSIGN)){
2005 strcpy(name,definitions->name);
2007 strcat(name,p2->name);
2009 len = sizeof(value);
2010 result=asn1_read_value(definitions,name,value,&len);
2012 if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
2014 p2=p2->right; /* pointer to the structure to
2015 use for expansion */
2016 while((p2) && (p2->type & CONST_ASSIGN))
2020 strcpy(name,definitions->name);
2022 strcat(name,p2->name);
2024 result=asn1_create_element(definitions,name,&aux);
2025 if(result == ASN1_SUCCESS){
2026 _asn1_set_name(aux,octetNode->name);
2027 len2=_asn1_get_length_der(octetNode->value,&len3);
2029 result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
2031 if(result == ASN1_SUCCESS){
2033 _asn1_set_right(aux,octetNode->right);
2034 _asn1_set_right(octetNode,aux);
2036 result=asn1_delete_structure(&octetNode);
2037 if(result == ASN1_SUCCESS){
2038 aux=ASN1_TYPE_EMPTY;
2041 else{ /* error with asn1_delete_structure */
2042 asn1_delete_structure(&aux);
2047 else{/* error with asn1_der_decoding */
2052 else{/* error with asn1_create_element */
2057 else{/* error with the pointer to the structure to exapand */
2058 retCode=ASN1_VALUE_NOT_VALID;
2068 if(!p2) retCode=ASN1_VALUE_NOT_VALID;