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
24 /*****************************************************/
25 /* File: decoding.c */
26 /* Description: Functions to manage DER decoding */
27 /*****************************************************/
32 #include "parser_aux.h"
34 #include "structure.h"
39 _asn1_error_description_tag_error(node_asn
*node
,char *ErrorDescription
)
42 Estrcpy(ErrorDescription
,":: tag error near element '");
43 _asn1_hierarchical_name(node
,ErrorDescription
+strlen(ErrorDescription
),
44 MAX_ERROR_DESCRIPTION_SIZE
-40);
45 Estrcat(ErrorDescription
,"'");
50 * asn1_get_length_der:
51 * @der: DER data to decode.
52 * @der_len: Length of DER data to decode.
53 * @len: Output variable containing the length of the DER length field.
55 * Extract a length field from DER data.
57 * Return value: Return the decoded length value, or -1 on indefinite
58 * length, or -2 when the value was too big.
61 asn1_get_length_der(const unsigned char *der
, int der_len
, int *len
)
67 if (der_len
<= 0) return 0;
78 if(k
){ /* definite length method */
80 while(punt
<=k
&& punt
< der_len
) {
81 unsigned long last
= ans
;
83 ans
=ans
*256+der
[punt
++];
85 /* we wrapped around, no bignum support... */
89 else{ /* indefinite length method */
103 * @der: DER data to decode.
104 * @der_len: Length of DER data to decode.
105 * @class: Output variable containing decoded class.
106 * @len: Output variable containing the length of the DER TAG data.
107 * @tag: Output variable containing the decoded tag.
109 * Decode the class and TAG from DER code.
111 * Return value: Returns ASN1_SUCCESS on success, or an error.
114 asn1_get_tag_der(const unsigned char *der
, int der_len
,
115 unsigned char *class,int *len
, unsigned long *tag
)
119 if (der
==NULL
|| der_len
<= 0 || len
== NULL
) return ASN1_DER_ERROR
;
122 if((der
[0]&0x1F)!=0x1F){
131 while(punt
<= der_len
&& der
[punt
]&128)
134 ris
=ris
*128+(der
[punt
++]&0x7F);
136 /* wrapper around, and no bignums... */
137 return ASN1_DER_ERROR
;
140 return ASN1_DER_ERROR
;
143 ris
=ris
*128+(der
[punt
++]&0x7F);
145 /* wrapper around, and no bignums... */
146 return ASN1_DER_ERROR
;
158 * asn1_get_octet_der:
159 * @der: DER data to decode containing the OCTET SEQUENCE.
160 * @der_len: Length of DER data to decode.
161 * @ret_len: Output variable containing the length of the DER data.
162 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
163 * @str_size: Length of pre-allocated output buffer.
164 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
166 * Extract an OCTET SEQUENCE from DER data.
168 * Return value: Returns ASN1_SUCCESS on success, or an error.
171 asn1_get_octet_der(const unsigned char *der
, int der_len
,
172 int *ret_len
,unsigned char *str
, int str_size
, int *str_len
)
176 if (der_len
<= 0) return ASN1_GENERIC_ERROR
;
178 /* if(str==NULL) return ASN1_SUCCESS; */
179 *str_len
=asn1_get_length_der(der
, der_len
, &len_len
);
182 return ASN1_DER_ERROR
;
184 *ret_len
=*str_len
+len_len
;
185 if ( str_size
>= *str_len
)
186 memcpy(str
,der
+len_len
,*str_len
);
188 return ASN1_MEM_ERROR
;
196 /* Returns ASN1_SUCCESS on success or an error code on error.
199 _asn1_get_time_der(const unsigned char *der
, int der_len
, int *ret_len
,unsigned char *str
,int str_size
)
203 if(der_len
<=0 || str
==NULL
) return ASN1_DER_ERROR
;
204 str_len
=asn1_get_length_der(der
, der_len
, &len_len
);
205 if (str_len
< 0 || str_size
< str_len
)
206 return ASN1_DER_ERROR
;
207 memcpy(str
,der
+len_len
,str_len
);
209 *ret_len
=str_len
+len_len
;
217 _asn1_get_objectid_der(const unsigned char *der
,int der_len
, int *ret_len
,unsigned char *str
, int str_size
)
221 unsigned long val
,val1
;
224 if (str
&& str_size
> 0) str
[0] = 0; /* no oid */
226 if(str
==NULL
|| der_len
<= 0) return;
227 len
=asn1_get_length_der(der
,der_len
, &len_len
);
229 if (len
< 0 || len
> der_len
|| len_len
> der_len
) return;
231 val1
=der
[len_len
]/40;
232 val
=der
[len_len
]-val1
*40;
234 _asn1_str_cpy(str
, str_size
, _asn1_ltostr(val1
,temp
));
235 _asn1_str_cat(str
, str_size
, ".");
236 _asn1_str_cat(str
, str_size
, _asn1_ltostr(val
,temp
));
241 val
|=der
[len_len
+k
]&0x7F;
242 if(!(der
[len_len
+k
]&0x80)){
243 _asn1_str_cat(str
, str_size
,".");
244 _asn1_str_cat(str
, str_size
,_asn1_ltostr(val
,temp
));
248 *ret_len
=len
+len_len
;
256 * @der: DER data to decode containing the BIT SEQUENCE.
257 * @der_len: Length of DER data to decode.
258 * @ret_len: Output variable containing the length of the DER data.
259 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
260 * @str_size: Length of pre-allocated output buffer.
261 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
263 * Extract a BIT SEQUENCE from DER data.
265 * Return value: Return ASN1_SUCCESS on success, or an error.
268 asn1_get_bit_der(const unsigned char *der
, int der_len
,
269 int *ret_len
, unsigned char *str
, int str_size
, int *bit_len
)
271 int len_len
,len_byte
;
273 if (der_len
<=0) return ASN1_GENERIC_ERROR
;
274 len_byte
=asn1_get_length_der(der
,der_len
,&len_len
)-1;
276 return ASN1_DER_ERROR
;
278 *ret_len
=len_byte
+len_len
+1;
279 *bit_len
=len_byte
*8-der
[len_len
];
281 if (str_size
>= len_byte
)
282 memcpy(str
,der
+len_len
+1,len_byte
);
284 return ASN1_MEM_ERROR
;
294 _asn1_extract_tag_der(node_asn
*node
,const unsigned char *der
, int der_len
,int *ret_len
)
297 int counter
,len2
,len3
,is_tag_implicit
;
298 unsigned long tag
,tag_implicit
=0;
299 unsigned char class,class2
,class_implicit
=0;
301 if (der_len
<= 0) return ASN1_GENERIC_ERROR
;
303 counter
=is_tag_implicit
=0;
305 if(node
->type
&CONST_TAG
){
308 if(type_field(p
->type
)==TYPE_TAG
){
309 if(p
->type
&CONST_APPLICATION
) class2
=APPLICATION
;
310 else if(p
->type
&CONST_UNIVERSAL
) class2
=UNIVERSAL
;
311 else if(p
->type
&CONST_PRIVATE
) class2
=PRIVATE
;
312 else class2
=CONTEXT_SPECIFIC
;
314 if(p
->type
&CONST_EXPLICIT
){
315 if (asn1_get_tag_der(der
+counter
, der_len
-counter
,&class,&len2
, &tag
)!=ASN1_SUCCESS
)
316 return ASN1_DER_ERROR
;
317 if (counter
+len2
> der_len
)
318 return ASN1_DER_ERROR
;
320 len3
=asn1_get_length_der(der
+counter
,der_len
-counter
, &len2
);
322 return ASN1_DER_ERROR
;
324 if(!is_tag_implicit
){
325 if((class!=(class2
|STRUCTURED
)) || (tag
!=strtoul(p
->value
,NULL
,10)))
326 return ASN1_TAG_ERROR
;
328 else{ /* TAG_IMPLICIT */
329 if((class!=class_implicit
) || (tag
!=tag_implicit
))
330 return ASN1_TAG_ERROR
;
335 else{ /* TAG_IMPLICIT */
336 if(!is_tag_implicit
){
337 if((type_field(node
->type
)==TYPE_SEQUENCE
) ||
338 (type_field(node
->type
)==TYPE_SEQUENCE_OF
) ||
339 (type_field(node
->type
)==TYPE_SET
) ||
340 (type_field(node
->type
)==TYPE_SET_OF
)) class2
|=STRUCTURED
;
341 class_implicit
=class2
;
342 tag_implicit
=strtoul(p
->value
,NULL
,10);
352 if (asn1_get_tag_der(der
+counter
, der_len
-counter
,&class,&len2
, &tag
)!=ASN1_SUCCESS
)
353 return ASN1_DER_ERROR
;
354 if (counter
+len2
> der_len
)
355 return ASN1_DER_ERROR
;
357 if((class!=class_implicit
) || (tag
!=tag_implicit
)){
358 if(type_field(node
->type
)==TYPE_OCTET_STRING
){
359 class_implicit
|= STRUCTURED
;
360 if((class!=class_implicit
) || (tag
!=tag_implicit
))
361 return ASN1_TAG_ERROR
;
364 return ASN1_TAG_ERROR
;
368 if(type_field(node
->type
)==TYPE_TAG
){
374 if (asn1_get_tag_der(der
+counter
, der_len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
375 return ASN1_DER_ERROR
;
376 if (counter
+len2
> der_len
)
377 return ASN1_DER_ERROR
;
379 switch(type_field(node
->type
)){
381 if((class!=UNIVERSAL
) || (tag
!=TAG_NULL
)) return ASN1_DER_ERROR
;
384 if((class!=UNIVERSAL
) || (tag
!=TAG_BOOLEAN
)) return ASN1_DER_ERROR
;
387 if((class!=UNIVERSAL
) || (tag
!=TAG_INTEGER
)) return ASN1_DER_ERROR
;
389 case TYPE_ENUMERATED
:
390 if((class!=UNIVERSAL
) || (tag
!=TAG_ENUMERATED
)) return ASN1_DER_ERROR
;
393 if((class!=UNIVERSAL
) || (tag
!=TAG_OBJECT_ID
)) return ASN1_DER_ERROR
;
396 if(node
->type
&CONST_UTC
){
397 if((class!=UNIVERSAL
) || (tag
!=TAG_UTCTime
)) return ASN1_DER_ERROR
;
400 if((class!=UNIVERSAL
) || (tag
!=TAG_GENERALIZEDTime
))
401 return ASN1_DER_ERROR
;
404 case TYPE_OCTET_STRING
:
405 if(((class!=UNIVERSAL
) && (class!=(UNIVERSAL
|STRUCTURED
)))
406 || (tag
!=TAG_OCTET_STRING
)) return ASN1_DER_ERROR
;
408 case TYPE_GENERALSTRING
:
409 if((class!=UNIVERSAL
) || (tag
!=TAG_GENERALSTRING
)) return ASN1_DER_ERROR
;
411 case TYPE_BIT_STRING
:
412 if((class!=UNIVERSAL
) || (tag
!=TAG_BIT_STRING
)) return ASN1_DER_ERROR
;
414 case TYPE_SEQUENCE
: case TYPE_SEQUENCE_OF
:
415 if((class!=(UNIVERSAL
|STRUCTURED
)) || (tag
!=TAG_SEQUENCE
))
416 return ASN1_DER_ERROR
;
418 case TYPE_SET
: case TYPE_SET_OF
:
419 if((class!=(UNIVERSAL
|STRUCTURED
)) || (tag
!=TAG_SET
))
420 return ASN1_DER_ERROR
;
426 return ASN1_DER_ERROR
;
438 _asn1_delete_not_used(node_asn
*node
)
442 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
446 if(p
->type
&CONST_NOT_USED
){
449 p2
=_asn1_find_left(p
);
450 if(!p2
) p2
=_asn1_find_up(p
);
452 asn1_delete_structure(&p
);
456 if(!p
) break; /* reach node */
463 else if(p
->right
) p
=p
->right
;
484 _asn1_get_octet_string(const unsigned char* der
, node_asn
*node
,int* len
)
486 int len2
,len3
,counter
,counter2
,counter_end
,tot_len
,indefinite
;
491 if(*(der
-1) & STRUCTURED
){
493 indefinite
=asn1_get_length_der(der
, *len
, &len3
);
495 return ASN1_DER_ERROR
;
498 if(indefinite
>=0) indefinite
+=len3
;
501 if(counter
>(*len
)) return ASN1_DER_ERROR
;
504 if((der
[counter
]==0) && (der
[counter
+1]==0)){
509 else if(counter
>=indefinite
) break;
511 if(der
[counter
] != TAG_OCTET_STRING
) return ASN1_DER_ERROR
;
515 len2
=asn1_get_length_der(der
+counter
,*len
-counter
, &len3
);
516 if(len2
<= 0) return ASN1_DER_ERROR
;
524 asn1_length_der(tot_len
,NULL
,&len2
);
525 temp
=(unsigned char *)_asn1_alloca(len2
+tot_len
);
527 return ASN1_MEM_ALLOC_ERROR
;
530 asn1_length_der(tot_len
,temp
,&len2
);
533 len2
=asn1_get_length_der(der
,*len
,&len3
);
534 if(len2
< -1) return ASN1_DER_ERROR
;
537 if(indefinite
==-1) counter_end
=counter
-2;
538 else counter_end
=counter
;
540 while(counter2
<counter_end
){
541 len2
=asn1_get_length_der(der
+counter2
, *len
-counter
, &len3
);
542 if(len2
< -1) return ASN1_DER_ERROR
;
544 /* FIXME: to be checked. Is this ok? Has the
545 * size been checked before?
547 memcpy(temp2
,der
+counter2
+len3
,len2
);
549 counter2
+=len2
+len3
+1;
552 _asn1_set_value(node
,temp
,tot_len
);
556 else{ /* NOT STRUCTURED */
557 len2
=asn1_get_length_der(der
, *len
, &len3
);
558 if(len2
< 0) return ASN1_DER_ERROR
;
559 if (len3
+len2
> *len
) return ASN1_DER_ERROR
;
561 _asn1_set_value(node
,der
,len3
+len2
);
572 _asn1_get_indefinite_length_string(const unsigned char* der
, int* len
)
574 int len2
,len3
,counter
,indefinite
;
578 counter
=indefinite
=0;
581 if((*len
)<counter
) return ASN1_DER_ERROR
;
583 if((der
[counter
]==0) && (der
[counter
+1]==0)){
586 if(indefinite
<=0) break;
590 if(asn1_get_tag_der(der
+counter
, *len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
591 return ASN1_DER_ERROR
;
592 if (counter
+len2
> *len
)
593 return ASN1_DER_ERROR
;
595 len2
=asn1_get_length_der(der
+counter
, *len
-counter
,&len3
);
596 if(len2
< -1) return ASN1_DER_ERROR
;
613 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
614 * @element: pointer to an ASN1 structure.
615 * @ider: vector that contains the DER encoding.
616 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
617 * @errorDescription: null-terminated string contains details when an
620 * Fill the structure *ELEMENT with values of a DER encoding
621 * string. The sructure must just be created with function
622 * 'create_stucture'. If an error occurs during the decoding
623 * procedure, the *ELEMENT is deleted and set equal to
628 * ASN1_SUCCESS: DER encoding OK.
630 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY.
632 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
633 * the structure NAME. *ELEMENT deleted.
637 asn1_der_decoding(ASN1_TYPE
*element
,const void *ider
,int len
,
638 char *errorDescription
)
640 node_asn
*node
,*p
,*p2
,*p3
;
642 int counter
,len2
,len3
,len4
,move
,ris
,tlen
;
643 unsigned char class,*temp2
;
645 int indefinite
, result
;
646 const unsigned char* der
= ider
;
650 if(node
==ASN1_TYPE_EMPTY
) return ASN1_ELEMENT_NOT_FOUND
;
652 if(node
->type
&CONST_OPTION
){
653 asn1_delete_structure(element
);
654 return ASN1_GENERIC_ERROR
;
663 if(p
->type
&CONST_SET
){
665 len2
=strtol(p2
->value
,NULL
,10);
667 if(!der
[counter
] && !der
[counter
+1]){
674 else if(counter
==len2
){
679 else if(counter
>len2
){
680 asn1_delete_structure(element
);
681 return ASN1_DER_ERROR
;
685 if((p2
->type
&CONST_SET
) && (p2
->type
&CONST_NOT_USED
)){
686 if(type_field(p2
->type
)!=TYPE_CHOICE
)
687 ris
=_asn1_extract_tag_der(p2
,der
+counter
,len
-counter
, &len2
);
691 ris
=_asn1_extract_tag_der(p3
,der
+counter
,len
-counter
, &len2
);
692 if(ris
==ASN1_SUCCESS
) break;
696 if(ris
==ASN1_SUCCESS
){
697 p2
->type
&=~CONST_NOT_USED
;
705 asn1_delete_structure(element
);
706 return ASN1_DER_ERROR
;
710 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
712 len2
=strtol(p2
->value
,NULL
,10);
720 if(p
->type
&CONST_OPTION
) asn1_delete_structure(&p
);
727 if(type_field(p
->type
)==TYPE_CHOICE
){
730 ris
=_asn1_extract_tag_der(p
->down
,der
+counter
,len
-counter
,&len2
);
733 if(ris
==ASN1_SUCCESS
){
734 while(p
->down
->right
){
736 asn1_delete_structure(&p2
);
740 else if(ris
==ASN1_ERROR_TYPE_ANY
){
741 asn1_delete_structure(element
);
742 return ASN1_ERROR_TYPE_ANY
;
746 asn1_delete_structure(&p2
);
751 if(!(p
->type
&CONST_OPTION
)){
752 asn1_delete_structure(element
);
753 return ASN1_DER_ERROR
;
760 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
762 len2
=strtol(p2
->value
,NULL
,10);
763 if((len2
!=-1) && (counter
>len2
)) ris
=ASN1_TAG_ERROR
;
766 if(ris
==ASN1_SUCCESS
) ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
767 if(ris
!=ASN1_SUCCESS
){
768 if(p
->type
&CONST_OPTION
){
769 p
->type
|=CONST_NOT_USED
;
772 else if(p
->type
&CONST_DEFAULT
) {
773 _asn1_set_value(p
,NULL
,0);
777 if (errorDescription
!=NULL
)
778 _asn1_error_description_tag_error(p
,errorDescription
);
780 asn1_delete_structure(element
);
781 return ASN1_TAG_ERROR
;
787 if(ris
==ASN1_SUCCESS
){
788 switch(type_field(p
->type
)){
791 asn1_delete_structure(element
);
792 return ASN1_DER_ERROR
;
798 if(der
[counter
++]!=1){
799 asn1_delete_structure(element
);
800 return ASN1_DER_ERROR
;
802 if(der
[counter
++]==0) _asn1_set_value(p
,"F",1);
803 else _asn1_set_value(p
,"T",1);
806 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
807 len2
=asn1_get_length_der(der
+counter
,len
-counter
, &len3
);
808 if(len2
< 0) return ASN1_DER_ERROR
;
809 if (len2
+len3
> len
-counter
) return ASN1_DER_ERROR
;
810 _asn1_set_value(p
,der
+counter
,len3
+len2
);
815 _asn1_get_objectid_der(der
+counter
,len
-counter
,&len2
, temp
, sizeof(temp
));
818 _asn1_set_value(p
,temp
,tlen
+1);
823 result
= _asn1_get_time_der(der
+counter
,len
-counter
,&len2
,temp
,sizeof(temp
)-1);
824 if (result
!= ASN1_SUCCESS
) {
825 asn1_delete_structure(element
);
830 _asn1_set_value(p
,temp
,tlen
+1);
834 case TYPE_OCTET_STRING
:
836 ris
=_asn1_get_octet_string(der
+counter
,p
,&len3
);
837 if(ris
!= ASN1_SUCCESS
) return ris
;
841 case TYPE_GENERALSTRING
:
842 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
843 if(len2
< 0) return ASN1_DER_ERROR
;
844 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
845 _asn1_set_value(p
,der
+counter
,len3
+len2
);
849 case TYPE_BIT_STRING
:
850 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
851 if(len2
< 0) return ASN1_DER_ERROR
;
852 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
853 _asn1_set_value(p
,der
+counter
,len3
+len2
);
857 case TYPE_SEQUENCE
: case TYPE_SET
:
859 len2
=strtol(p
->value
,NULL
,10);
860 _asn1_set_value(p
,NULL
,0);
861 if(len2
==-1){ /* indefinite length method */
862 if (len
-counter
+1 > 0) {
863 if((der
[counter
]) || der
[counter
+1]){
864 asn1_delete_structure(element
);
865 return ASN1_DER_ERROR
;
867 } else return ASN1_DER_ERROR
;
870 else{ /* definite length method */
872 asn1_delete_structure(element
);
873 return ASN1_DER_ERROR
;
878 else{ /* move==DOWN || move==RIGHT */
879 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
880 if(len3
< -1) return ASN1_DER_ERROR
;
883 _asn1_ltostr(counter
+len3
,temp
);
886 _asn1_set_value(p
,temp
,tlen
+1);
892 if(type_field(p2
->type
)!=TYPE_TAG
){
894 asn1_delete_structure(&p2
);
902 else{ /* indefinite length method */
903 _asn1_set_value(p
,"-1",3);
908 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
910 len2
=strtol(p
->value
,NULL
,10);
911 if(len2
==-1){ /* indefinite length method */
912 if((counter
+2)>len
) return ASN1_DER_ERROR
;
913 if((der
[counter
]) || der
[counter
+1]){
914 _asn1_append_sequence_set(p
);
916 while(p
->right
) p
=p
->right
;
920 _asn1_set_value(p
,NULL
,0);
923 else{ /* definite length method */
925 _asn1_append_sequence_set(p
);
927 while(p
->right
) p
=p
->right
;
931 _asn1_set_value(p
,NULL
,0);
933 asn1_delete_structure(element
);
934 return ASN1_DER_ERROR
;
938 else{ /* move==DOWN || move==RIGHT */
939 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
940 if(len3
< -1) return ASN1_DER_ERROR
;
943 if(len3
>0){ /* definite length method */
944 _asn1_ltostr(counter
+len3
,temp
);
948 _asn1_set_value(p
,temp
,tlen
+1);
950 else { /* indefinite length method */
951 _asn1_set_value(p
,"-1",3);
954 while((type_field(p2
->type
)==TYPE_TAG
) || (type_field(p2
->type
)==TYPE_SIZE
)) p2
=p2
->right
;
955 if(p2
->right
==NULL
) _asn1_append_sequence_set(p
);
962 if(asn1_get_tag_der(der
+counter
,len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
963 return ASN1_DER_ERROR
;
964 if (counter
+len2
> len
)
965 return ASN1_DER_ERROR
;
966 len4
=asn1_get_length_der(der
+counter
+len2
,len
-counter
-len2
,&len3
);
967 if(len4
< -1) return ASN1_DER_ERROR
;
968 if(len4
> len
-counter
+len2
+len3
) return ASN1_DER_ERROR
;
971 asn1_length_der(len2
+len3
,NULL
,&len4
);
972 temp2
=(unsigned char *)_asn1_alloca(len2
+len3
+len4
);
974 asn1_delete_structure(element
);
975 return ASN1_MEM_ALLOC_ERROR
;
978 asn1_octet_der(der
+counter
,len2
+len3
,temp2
,&len4
);
979 _asn1_set_value(p
,temp2
,len4
);
983 else{ /* indefinite length */
984 /* Check indefinite lenth method in an EXPLICIT TAG */
985 if((p
->type
&CONST_TAG
) && (der
[counter
-1]==0x80))
991 ris
=_asn1_get_indefinite_length_string(der
+counter
,&len2
);
992 if(ris
!= ASN1_SUCCESS
){
993 asn1_delete_structure(element
);
996 asn1_length_der(len2
,NULL
,&len4
);
997 temp2
=(unsigned char *)_asn1_alloca(len2
+len4
);
999 asn1_delete_structure(element
);
1000 return ASN1_MEM_ALLOC_ERROR
;
1003 asn1_octet_der(der
+counter
,len2
,temp2
,&len4
);
1004 _asn1_set_value(p
,temp2
,len4
);
1008 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1009 an indefinite length method. */
1011 if(!der
[counter
] && !der
[counter
+1]){
1015 asn1_delete_structure(element
);
1016 return ASN1_DER_ERROR
;
1023 move
=(move
==UP
)?RIGHT
:DOWN
;
1028 if(p
==node
&& move
!=DOWN
) break;
1031 if(p
->down
) p
=p
->down
;
1034 if((move
==RIGHT
) && !(p
->type
&CONST_SET
)){
1035 if(p
->right
) p
=p
->right
;
1038 if(move
==UP
) p
=_asn1_find_up(p
);
1041 _asn1_delete_not_used(*element
);
1044 asn1_delete_structure(element
);
1045 return ASN1_DER_ERROR
;
1048 return ASN1_SUCCESS
;
1053 #define SAME_BRANCH 2
1054 #define OTHER_BRANCH 3
1058 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
1059 * @structure: pointer to an ASN1 structure
1060 * @elementName: name of the element to fill
1061 * @ider: vector that contains the DER encoding of the whole structure.
1062 * @len: number of bytes of *der: der[0]..der[len-1]
1063 * @errorDescription: null-terminated string contains details when an
1066 * Fill the element named ELEMENTNAME with values of a DER encoding
1067 * string. The sructure must just be created with function
1068 * 'create_stucture'. The DER vector must contain the encoding
1069 * string of the whole STRUCTURE. If an error occurs during the
1070 * decoding procedure, the *STRUCTURE is deleted and set equal to
1075 * ASN1_SUCCESS: DER encoding OK.
1077 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or
1078 * elementName == NULL.
1080 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
1081 * the structure STRUCTURE. *ELEMENT deleted.
1085 asn1_der_decoding_element(ASN1_TYPE
*structure
,const char *elementName
,
1086 const void *ider
,int len
,char *errorDescription
)
1088 node_asn
*node
,*p
,*p2
,*p3
,*nodeFound
=ASN1_TYPE_EMPTY
;
1089 char temp
[128],currentName
[MAX_NAME_SIZE
*10],*dot_p
,*char_p
;
1090 int nameLen
=MAX_NAME_SIZE
*10-1,state
;
1091 int counter
,len2
,len3
,len4
,move
,ris
, tlen
;
1092 unsigned char class,*temp2
;
1094 int indefinite
, result
;
1095 const unsigned char* der
= ider
;
1099 if(node
==ASN1_TYPE_EMPTY
) return ASN1_ELEMENT_NOT_FOUND
;
1101 if(elementName
== NULL
){
1102 asn1_delete_structure(structure
);
1103 return ASN1_ELEMENT_NOT_FOUND
;
1106 if(node
->type
&CONST_OPTION
){
1107 asn1_delete_structure(structure
);
1108 return ASN1_GENERIC_ERROR
;
1111 if((*structure
)->name
){ /* Has *structure got a name? */
1112 nameLen
-=strlen((*structure
)->name
);
1113 if(nameLen
>0) strcpy(currentName
,(*structure
)->name
);
1115 asn1_delete_structure(structure
);
1116 return ASN1_MEM_ERROR
;
1118 if(!(strcmp(currentName
,elementName
))){
1120 nodeFound
=*structure
;
1122 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1127 else{ /* *structure doesn't have a name? */
1129 if(elementName
[0]==0){
1131 nodeFound
=*structure
;
1146 if(p
->type
&CONST_SET
){
1147 p2
=_asn1_find_up(p
);
1148 len2
=strtol(p2
->value
,NULL
,10);
1154 else if(counter
>len2
){
1155 asn1_delete_structure(structure
);
1156 return ASN1_DER_ERROR
;
1160 if((p2
->type
&CONST_SET
) && (p2
->type
&CONST_NOT_USED
)){
1161 if(type_field(p2
->type
)!=TYPE_CHOICE
)
1162 ris
=_asn1_extract_tag_der(p2
,der
+counter
,len
-counter
,&len2
);
1166 ris
=_asn1_extract_tag_der(p3
,der
+counter
,len
-counter
,&len2
);
1167 if(ris
==ASN1_SUCCESS
) break;
1171 if(ris
==ASN1_SUCCESS
){
1172 p2
->type
&=~CONST_NOT_USED
;
1180 asn1_delete_structure(structure
);
1181 return ASN1_DER_ERROR
;
1185 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
1186 p2
=_asn1_find_up(p
);
1187 len2
=strtol(p2
->value
,NULL
,10);
1195 if(p
->type
&CONST_OPTION
) asn1_delete_structure(&p
);
1202 if(type_field(p
->type
)==TYPE_CHOICE
){
1205 ris
=_asn1_extract_tag_der(p
->down
,der
+counter
,len
-counter
,&len2
);
1208 if(ris
==ASN1_SUCCESS
){
1209 while(p
->down
->right
){
1211 asn1_delete_structure(&p2
);
1215 else if(ris
==ASN1_ERROR_TYPE_ANY
){
1216 asn1_delete_structure(structure
);
1217 return ASN1_ERROR_TYPE_ANY
;
1221 asn1_delete_structure(&p2
);
1226 if(!(p
->type
&CONST_OPTION
)){
1227 asn1_delete_structure(structure
);
1228 return ASN1_DER_ERROR
;
1235 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
1236 p2
=_asn1_find_up(p
);
1237 len2
=strtol(p2
->value
,NULL
,10);
1238 if(counter
>len2
) ris
=ASN1_TAG_ERROR
;
1241 if(ris
==ASN1_SUCCESS
) ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
1242 if(ris
!=ASN1_SUCCESS
){
1243 if(p
->type
&CONST_OPTION
){
1244 p
->type
|=CONST_NOT_USED
;
1247 else if(p
->type
&CONST_DEFAULT
) {
1248 _asn1_set_value(p
,NULL
,0);
1252 if (errorDescription
!=NULL
)
1253 _asn1_error_description_tag_error(p
,errorDescription
);
1255 asn1_delete_structure(structure
);
1256 return ASN1_TAG_ERROR
;
1262 if(ris
==ASN1_SUCCESS
){
1263 switch(type_field(p
->type
)){
1266 asn1_delete_structure(structure
);
1267 return ASN1_DER_ERROR
;
1270 if(p
==nodeFound
) state
=EXIT
;
1276 if(der
[counter
++]!=1){
1277 asn1_delete_structure(structure
);
1278 return ASN1_DER_ERROR
;
1282 if(der
[counter
++]==0) _asn1_set_value(p
,"F",1);
1283 else _asn1_set_value(p
,"T",1);
1285 if(p
==nodeFound
) state
=EXIT
;
1293 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
1294 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1295 if(len2
< 0) return ASN1_DER_ERROR
;
1297 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
1298 _asn1_set_value(p
,der
+counter
,len3
+len2
);
1300 if(p
==nodeFound
) state
=EXIT
;
1305 case TYPE_OBJECT_ID
:
1307 _asn1_get_objectid_der(der
+counter
,len
-counter
,&len2
, temp
, sizeof(temp
));
1308 tlen
= strlen(temp
);
1311 _asn1_set_value(p
,temp
,tlen
+1);
1313 if(p
==nodeFound
) state
=EXIT
;
1316 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1317 if(len2
< 0) return ASN1_DER_ERROR
;
1326 result
= _asn1_get_time_der(der
+counter
,len
-counter
,&len2
,temp
,sizeof(temp
)-1);
1327 if (result
!= ASN1_SUCCESS
) {
1328 asn1_delete_structure(structure
);
1332 tlen
= strlen(temp
);
1334 _asn1_set_value(p
,temp
,tlen
+1);
1336 if(p
==nodeFound
) state
=EXIT
;
1339 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1340 if(len2
< 0) return ASN1_DER_ERROR
;
1347 case TYPE_OCTET_STRING
:
1350 ris
=_asn1_get_octet_string(der
+counter
,p
,&len3
);
1351 if(p
==nodeFound
) state
=EXIT
;
1354 ris
=_asn1_get_octet_string(der
+counter
,NULL
,&len3
);
1356 if(ris
!= ASN1_SUCCESS
) return ris
;
1360 case TYPE_GENERALSTRING
:
1361 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1362 if(len2
< 0) return ASN1_DER_ERROR
;
1364 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
1365 _asn1_set_value(p
,der
+counter
,len3
+len2
);
1367 if(p
==nodeFound
) state
=EXIT
;
1372 case TYPE_BIT_STRING
:
1373 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1374 if(len2
< 0) return ASN1_DER_ERROR
;
1376 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
1377 _asn1_set_value(p
,der
+counter
,len3
+len2
);
1379 if(p
==nodeFound
) state
=EXIT
;
1384 case TYPE_SEQUENCE
: case TYPE_SET
:
1386 len2
=strtol(p
->value
,NULL
,10);
1387 _asn1_set_value(p
,NULL
,0);
1388 if(len2
==-1){ /* indefinite length method */
1389 if((der
[counter
]) || der
[counter
+1]){
1390 asn1_delete_structure(structure
);
1391 return ASN1_DER_ERROR
;
1395 else{ /* definite length method */
1397 asn1_delete_structure(structure
);
1398 return ASN1_DER_ERROR
;
1401 if(p
==nodeFound
) state
=EXIT
;
1404 else{ /* move==DOWN || move==RIGHT */
1405 if(state
==OTHER_BRANCH
){
1406 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1407 if(len3
< 0) return ASN1_DER_ERROR
;
1411 else { /* state==SAME_BRANCH or state==FOUND */
1412 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1413 if(len3
< 0) return ASN1_DER_ERROR
;
1416 _asn1_ltostr(counter
+len3
,temp
);
1417 tlen
= strlen(temp
);
1420 _asn1_set_value(p
,temp
,tlen
+1);
1426 if(type_field(p2
->type
)!=TYPE_TAG
){
1428 asn1_delete_structure(&p2
);
1436 else{ /* indefinite length method */
1437 _asn1_set_value(p
,"-1",3);
1443 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
1445 len2
=strtol(p
->value
,NULL
,10);
1447 _asn1_append_sequence_set(p
);
1449 while(p
->right
) p
=p
->right
;
1453 _asn1_set_value(p
,NULL
,0);
1455 asn1_delete_structure(structure
);
1456 return ASN1_DER_ERROR
;
1459 if(p
==nodeFound
) state
=EXIT
;
1461 else{ /* move==DOWN || move==RIGHT */
1462 if(state
==OTHER_BRANCH
){
1463 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1464 if(len3
< 0) return ASN1_DER_ERROR
;
1468 else{ /* state==FOUND or state==SAME_BRANCH */
1469 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1470 if(len3
< 0) return ASN1_DER_ERROR
;
1473 _asn1_ltostr(counter
+len3
,temp
);
1474 tlen
= strlen(temp
);
1477 _asn1_set_value(p
,temp
,tlen
+1);
1479 while((type_field(p2
->type
)==TYPE_TAG
) || (type_field(p2
->type
)==TYPE_SIZE
)) p2
=p2
->right
;
1480 if(p2
->right
==NULL
) _asn1_append_sequence_set(p
);
1489 if(asn1_get_tag_der(der
+counter
, len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
1490 return ASN1_DER_ERROR
;
1491 if (counter
+len2
> len
)
1492 return ASN1_DER_ERROR
;
1494 len4
=asn1_get_length_der(der
+counter
+len2
,len
-counter
-len2
,&len3
);
1495 if(len4
< -1) return ASN1_DER_ERROR
;
1500 asn1_length_der(len2
+len3
,NULL
,&len4
);
1501 temp2
=(unsigned char *)_asn1_alloca(len2
+len3
+len4
);
1503 asn1_delete_structure(structure
);
1504 return ASN1_MEM_ALLOC_ERROR
;
1507 asn1_octet_der(der
+counter
,len2
+len3
,temp2
,&len4
);
1508 _asn1_set_value(p
,temp2
,len4
);
1511 if(p
==nodeFound
) state
=EXIT
;
1515 else{ /* indefinite length */
1516 /* Check indefinite lenth method in an EXPLICIT TAG */
1517 if((p
->type
&CONST_TAG
) && (der
[counter
-1]==0x80))
1523 ris
=_asn1_get_indefinite_length_string(der
+counter
,&len2
);
1524 if(ris
!= ASN1_SUCCESS
){
1525 asn1_delete_structure(structure
);
1530 asn1_length_der(len2
,NULL
,&len4
);
1531 temp2
=(unsigned char *)_asn1_alloca(len2
+len4
);
1533 asn1_delete_structure(structure
);
1534 return ASN1_MEM_ALLOC_ERROR
;
1537 asn1_octet_der(der
+counter
,len2
,temp2
,&len4
);
1538 _asn1_set_value(p
,temp2
,len4
);
1541 if(p
==nodeFound
) state
=EXIT
;
1546 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1547 an indefinite length method. */
1549 if(!der
[counter
] && !der
[counter
+1]){
1553 asn1_delete_structure(structure
);
1554 return ASN1_DER_ERROR
;
1562 move
=(move
==UP
)?RIGHT
:DOWN
;
1567 if((p
==node
&& move
!=DOWN
) || (state
==EXIT
)) break;
1574 nameLen
-=strlen(p
->name
)+1;
1576 if(currentName
[0]) strcat(currentName
,".");
1577 strcat(currentName
,p
->name
);
1580 asn1_delete_structure(structure
);
1581 return ASN1_MEM_ERROR
;
1583 if(!(strcmp(currentName
,elementName
))){
1587 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1596 if((move
==RIGHT
) && !(p
->type
&CONST_SET
)){
1601 dot_p
=char_p
=currentName
;
1602 while((char_p
=strchr(char_p
,'.'))){
1607 nameLen
+=strlen(currentName
)-(dot_p
-currentName
);
1610 nameLen
-=strlen(p
->name
);
1611 if(nameLen
>0) strcat(currentName
,p
->name
);
1613 asn1_delete_structure(structure
);
1614 return ASN1_MEM_ERROR
;
1617 if(!(strcmp(currentName
,elementName
))){
1621 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1634 dot_p
=char_p
=currentName
;
1635 while((char_p
=strchr(char_p
,'.'))){
1640 nameLen
+=strlen(currentName
)-(dot_p
-currentName
);
1643 if(!(strcmp(currentName
,elementName
))){
1647 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1655 _asn1_delete_not_used(*structure
);
1658 asn1_delete_structure(structure
);
1659 return ASN1_DER_ERROR
;
1662 return ASN1_SUCCESS
;
1668 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1669 * @element: pointer to an ASN1 element
1670 * @ider: vector that contains the DER encoding.
1671 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
1672 * @name_element: an element of NAME structure.
1673 * @start: the position of the first byte of NAME_ELEMENT decoding
1675 * @end: the position of the last byte of NAME_ELEMENT decoding
1678 * Find the start and end point of an element in a DER encoding
1679 * string. I mean that if you have a der encoding and you have
1680 * already used the function "asn1_der_decoding" to fill a structure,
1681 * it may happen that you want to find the piece of string concerning
1682 * an element of the structure.
1684 * Example: the sequence "tbsCertificate" inside an X509 certificate.
1688 * ASN1_SUCCESS: DER encoding OK.
1690 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or
1691 * NAME_ELEMENT is not a valid element.
1693 * ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match
1694 * the structure ELEMENT.
1698 asn1_der_decoding_startEnd(ASN1_TYPE element
,const void *ider
,int len
,
1699 const char *name_element
,int *start
, int *end
)
1701 node_asn
*node
,*node_to_find
,*p
,*p2
,*p3
;
1702 int counter
,len2
,len3
,len4
,move
,ris
;
1703 unsigned char class;
1706 const unsigned char* der
= ider
;
1710 if(node
==ASN1_TYPE_EMPTY
) return ASN1_ELEMENT_NOT_FOUND
;
1712 node_to_find
=_asn1_find_node(node
,name_element
);
1714 if(node_to_find
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
1716 if(node_to_find
==node
){
1719 return ASN1_SUCCESS
;
1722 if(node
->type
&CONST_OPTION
) return ASN1_GENERIC_ERROR
;
1731 if(p
->type
&CONST_SET
){
1732 p2
=_asn1_find_up(p
);
1733 len2
=strtol(p2
->value
,NULL
,10);
1735 if(!der
[counter
] && !der
[counter
+1]){
1742 else if(counter
==len2
){
1747 else if(counter
>len2
) return ASN1_DER_ERROR
;
1750 if((p2
->type
&CONST_SET
) && (p2
->type
&CONST_NOT_USED
)){ /* CONTROLLARE */
1751 if(type_field(p2
->type
)!=TYPE_CHOICE
)
1752 ris
=_asn1_extract_tag_der(p2
,der
+counter
,len
-counter
,&len2
);
1755 ris
=_asn1_extract_tag_der(p3
,der
+counter
,len
-counter
,&len2
);
1757 if(ris
==ASN1_SUCCESS
){
1758 p2
->type
&=~CONST_NOT_USED
;
1765 if(p2
==NULL
) return ASN1_DER_ERROR
;
1768 if(p
==node_to_find
) *start
=counter
;
1770 if(type_field(p
->type
)==TYPE_CHOICE
){
1772 ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
1773 if(p
==node_to_find
) *start
=counter
;
1776 if(ris
==ASN1_SUCCESS
) ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
1777 if(ris
!=ASN1_SUCCESS
){
1778 if(p
->type
&CONST_OPTION
){
1779 p
->type
|=CONST_NOT_USED
;
1782 else if(p
->type
&CONST_DEFAULT
) {
1786 return ASN1_TAG_ERROR
;
1792 if(ris
==ASN1_SUCCESS
){
1793 switch(type_field(p
->type
)){
1795 if(der
[counter
]) return ASN1_DER_ERROR
;
1800 if(der
[counter
++]!=1) return ASN1_DER_ERROR
;
1804 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
1805 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1806 if(len2
< 0) return ASN1_DER_ERROR
;
1810 case TYPE_OBJECT_ID
:
1811 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1812 if(len2
< 0) return ASN1_DER_ERROR
;
1817 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1818 if(len2
< 0) return ASN1_DER_ERROR
;
1822 case TYPE_OCTET_STRING
:
1824 ris
=_asn1_get_octet_string(der
+counter
,NULL
,&len3
);
1825 if(ris
!= ASN1_SUCCESS
) return ris
;
1829 case TYPE_GENERALSTRING
:
1830 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1831 if(len2
< 0) return ASN1_DER_ERROR
;
1835 case TYPE_BIT_STRING
:
1836 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1837 if(len2
< 0) return ASN1_DER_ERROR
;
1841 case TYPE_SEQUENCE
: case TYPE_SET
:
1843 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1844 if(len3
< -1) return ASN1_DER_ERROR
;
1846 if(len3
==0) move
=RIGHT
;
1850 if(!der
[counter
] && !der
[counter
+1]) /* indefinite length method */
1855 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
1857 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1858 if(len3
< -1) return ASN1_DER_ERROR
;
1860 if((len3
==-1) && !der
[counter
] && !der
[counter
+1])
1864 while((type_field(p2
->type
)==TYPE_TAG
) ||
1865 (type_field(p2
->type
)==TYPE_SIZE
)) p2
=p2
->right
;
1870 if(!der
[counter
] && !der
[counter
+1]) /* indefinite length method */
1876 if (asn1_get_tag_der(der
+counter
, len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
1877 return ASN1_DER_ERROR
;
1878 if (counter
+len2
> len
)
1879 return ASN1_DER_ERROR
;
1881 len4
=asn1_get_length_der(der
+counter
+len2
,len
-counter
-len2
,&len3
);
1882 if(len4
< -1) return ASN1_DER_ERROR
;
1885 counter
+=len2
+len4
+len3
;
1887 else{ /* indefinite length */
1888 /* Check indefinite lenth method in an EXPLICIT TAG */
1889 if((p
->type
&CONST_TAG
) && (der
[counter
-1]==0x80))
1895 ris
=_asn1_get_indefinite_length_string(der
+counter
,&len2
);
1896 if(ris
!= ASN1_SUCCESS
)
1900 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1901 an indefinite length method. */
1903 if(!der
[counter
] && !der
[counter
+1])
1906 return ASN1_DER_ERROR
;
1912 move
=(move
==UP
)?RIGHT
:DOWN
;
1917 if((p
==node_to_find
) && (move
==RIGHT
)){
1919 return ASN1_SUCCESS
;
1922 if(p
==node
&& move
!=DOWN
) break;
1925 if(p
->down
) p
=p
->down
;
1928 if((move
==RIGHT
) && !(p
->type
&CONST_SET
)){
1929 if(p
->right
) p
=p
->right
;
1932 if(move
==UP
) p
=_asn1_find_up(p
);
1935 return ASN1_ELEMENT_NOT_FOUND
;
1940 * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure.
1941 * @definitions: ASN1 definitions
1942 * @element: pointer to an ASN1 structure
1944 * Expands every "ANY DEFINED BY" element of a structure created from
1945 * a DER decoding process (asn1_der_decoding function). The element ANY
1946 * must be defined by an OBJECT IDENTIFIER. The type used to expand
1947 * the element ANY is the first one following the definition of
1948 * the actual value of the OBJECT IDENTIFIER.
1953 * ASN1_SUCCESS: Substitution OK.
1955 * ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be
1956 * expanded due to a problem in OBJECT_ID -> TYPE association.
1958 * other errors: Result of der decoding process.
1962 asn1_expand_any_defined_by(ASN1_TYPE definitions
,ASN1_TYPE
*element
)
1964 char definitionsName
[MAX_NAME_SIZE
],name
[2*MAX_NAME_SIZE
+1],value
[MAX_NAME_SIZE
];
1965 asn1_retCode retCode
=ASN1_SUCCESS
,result
;
1967 ASN1_TYPE p
,p2
,p3
,aux
=ASN1_TYPE_EMPTY
;
1968 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
1970 if((definitions
==ASN1_TYPE_EMPTY
) || (*element
==ASN1_TYPE_EMPTY
))
1971 return ASN1_ELEMENT_NOT_FOUND
;
1973 strcpy(definitionsName
,definitions
->name
);
1974 strcat(definitionsName
,".");
1979 switch(type_field(p
->type
)){
1981 if((p
->type
&CONST_DEFINED_BY
) && (p
->value
)){
1982 /* search the "DEF_BY" element */
1984 while((p2
) && (type_field(p2
->type
)!=TYPE_CONSTANT
))
1988 retCode
=ASN1_ERROR_TYPE_ANY
;
1992 p3
=_asn1_find_up(p
);
1995 retCode
=ASN1_ERROR_TYPE_ANY
;
2001 if((p3
->name
) && !(strcmp(p3
->name
,p2
->name
))) break;
2005 if((!p3
) || (type_field(p3
->type
)!=TYPE_OBJECT_ID
) ||
2008 p3
=_asn1_find_up(p
);
2009 p3
=_asn1_find_up(p3
);
2012 retCode
=ASN1_ERROR_TYPE_ANY
;
2019 if((p3
->name
) && !(strcmp(p3
->name
,p2
->name
))) break;
2023 if((!p3
) || (type_field(p3
->type
)!=TYPE_OBJECT_ID
) ||
2025 retCode
=ASN1_ERROR_TYPE_ANY
;
2030 /* search the OBJECT_ID into definitions */
2031 p2
=definitions
->down
;
2033 if((type_field(p2
->type
)==TYPE_OBJECT_ID
) &&
2034 (p2
->type
& CONST_ASSIGN
)){
2035 strcpy(name
,definitionsName
);
2036 strcat(name
,p2
->name
);
2039 result
=asn1_read_value(definitions
,name
,value
,&len
);
2041 if((result
== ASN1_SUCCESS
) && (!strcmp(p3
->value
,value
))){
2042 p2
=p2
->right
; /* pointer to the structure to
2043 use for expansion */
2044 while((p2
) && (p2
->type
& CONST_ASSIGN
))
2048 strcpy(name
,definitionsName
);
2049 strcat(name
,p2
->name
);
2051 result
=asn1_create_element(definitions
,name
,&aux
);
2052 if(result
== ASN1_SUCCESS
){
2053 _asn1_set_name(aux
,p
->name
);
2054 len2
=asn1_get_length_der(p
->value
,p
->value_len
,&len3
);
2055 if(len2
< 0) return ASN1_DER_ERROR
;
2057 result
=asn1_der_decoding(&aux
,p
->value
+len3
,len2
,
2059 if(result
== ASN1_SUCCESS
){
2061 _asn1_set_right(aux
,p
->right
);
2062 _asn1_set_right(p
,aux
);
2064 result
=asn1_delete_structure(&p
);
2065 if(result
== ASN1_SUCCESS
){
2067 aux
=ASN1_TYPE_EMPTY
;
2070 else{ /* error with asn1_delete_structure */
2071 asn1_delete_structure(&aux
);
2076 else{/* error with asn1_der_decoding */
2081 else{/* error with asn1_create_element */
2086 else{/* error with the pointer to the structure to exapand */
2087 retCode
=ASN1_ERROR_TYPE_ANY
;
2096 retCode
=ASN1_ERROR_TYPE_ANY
;
2110 else if(p
==*element
){
2114 else if(p
->right
) p
=p
->right
;
2136 * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure.
2137 * @definitions: ASN1 definitions
2138 * @element: pointer to an ASN1 structure
2139 * @octetName: name of the OCTECT STRING field to expand.
2140 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2141 * the type for expansion.
2143 * Expands an "OCTET STRING" element of a structure created from a
2144 * DER decoding process (asn1_der_decoding function). The type used
2145 * for expansion is the first one following the definition of the
2146 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2150 * ASN1_SUCCESS: Substitution OK.
2152 * ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct.
2154 * ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use
2157 * other errors: result of der decoding process.
2160 asn1_expand_octet_string(ASN1_TYPE definitions
,ASN1_TYPE
*element
,
2161 const char *octetName
,const char *objectName
)
2163 char name
[2*MAX_NAME_SIZE
+1],value
[MAX_NAME_SIZE
];
2164 asn1_retCode retCode
=ASN1_SUCCESS
,result
;
2166 ASN1_TYPE p2
,aux
=ASN1_TYPE_EMPTY
;
2167 ASN1_TYPE octetNode
=ASN1_TYPE_EMPTY
,objectNode
=ASN1_TYPE_EMPTY
;
2168 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
2170 if((definitions
==ASN1_TYPE_EMPTY
) || (*element
==ASN1_TYPE_EMPTY
))
2171 return ASN1_ELEMENT_NOT_FOUND
;
2173 octetNode
=_asn1_find_node(*element
,octetName
);
2174 if(octetNode
==ASN1_TYPE_EMPTY
)
2175 return ASN1_ELEMENT_NOT_FOUND
;
2176 if(type_field(octetNode
->type
)!=TYPE_OCTET_STRING
)
2177 return ASN1_ELEMENT_NOT_FOUND
;
2178 if(octetNode
->value
==NULL
)
2179 return ASN1_VALUE_NOT_FOUND
;
2181 objectNode
=_asn1_find_node(*element
,objectName
);
2182 if(objectNode
==ASN1_TYPE_EMPTY
)
2183 return ASN1_ELEMENT_NOT_FOUND
;
2185 if(type_field(objectNode
->type
)!=TYPE_OBJECT_ID
)
2186 return ASN1_ELEMENT_NOT_FOUND
;
2188 if(objectNode
->value
==NULL
)
2189 return ASN1_VALUE_NOT_FOUND
;
2192 /* search the OBJECT_ID into definitions */
2193 p2
=definitions
->down
;
2195 if((type_field(p2
->type
)==TYPE_OBJECT_ID
) &&
2196 (p2
->type
& CONST_ASSIGN
)){
2197 strcpy(name
,definitions
->name
);
2199 strcat(name
,p2
->name
);
2201 len
= sizeof(value
);
2202 result
=asn1_read_value(definitions
,name
,value
,&len
);
2204 if((result
== ASN1_SUCCESS
) && (!strcmp(objectNode
->value
,value
))){
2206 p2
=p2
->right
; /* pointer to the structure to
2207 use for expansion */
2208 while((p2
) && (p2
->type
& CONST_ASSIGN
))
2212 strcpy(name
,definitions
->name
);
2214 strcat(name
,p2
->name
);
2216 result
=asn1_create_element(definitions
,name
,&aux
);
2217 if(result
== ASN1_SUCCESS
){
2218 _asn1_set_name(aux
,octetNode
->name
);
2219 len2
=asn1_get_length_der(octetNode
->value
,octetNode
->value_len
,&len3
);
2220 if(len2
< 0) return ASN1_DER_ERROR
;
2222 result
=asn1_der_decoding(&aux
,octetNode
->value
+len3
,len2
,
2224 if(result
== ASN1_SUCCESS
){
2226 _asn1_set_right(aux
,octetNode
->right
);
2227 _asn1_set_right(octetNode
,aux
);
2229 result
=asn1_delete_structure(&octetNode
);
2230 if(result
== ASN1_SUCCESS
){
2231 aux
=ASN1_TYPE_EMPTY
;
2234 else{ /* error with asn1_delete_structure */
2235 asn1_delete_structure(&aux
);
2240 else{/* error with asn1_der_decoding */
2245 else{/* error with asn1_create_element */
2250 else{/* error with the pointer to the structure to exapand */
2251 retCode
=ASN1_VALUE_NOT_VALID
;
2261 if(!p2
) retCode
=ASN1_VALUE_NOT_VALID
;