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
,"'");
51 asn1_get_length_der(const unsigned char *der
, int der_len
, int *len
)
57 if (der_len
<= 0) return 0;
68 if(k
){ /* definite length method */
70 while(punt
<=k
&& punt
< der_len
) {
71 unsigned long last
= ans
;
72 ans
=ans
*256+der
[punt
++];
74 /* we wrapped around, no bignum support... */
78 else{ /* indefinite length method */
92 * @der: DER data to decode.
93 * @der_len: Length of DER data to decode.
94 * @class: Output variable containing decoded class.
95 * @len: Output variable containing the length of the DER TAG data.
96 * @tag: Output variable containing the decoded tag.
98 * Decode the class and TAG from DER code.
100 * Return value: Returns ASN1_SUCCESS on success, or an error.
103 asn1_get_tag_der(const unsigned char *der
, int der_len
,
104 unsigned char *class,int *len
, unsigned long *tag
)
108 if (der
==NULL
|| der_len
<= 0 || len
== NULL
) return ASN1_DER_ERROR
;
111 if((der
[0]&0x1F)!=0x1F){
120 while(punt
<= der_len
&& der
[punt
]&128)
123 ris
=ris
*128+(der
[punt
++]&0x7F);
125 /* wrapper around, and no bignums... */
126 return ASN1_DER_ERROR
;
129 return ASN1_DER_ERROR
;
132 ris
=ris
*128+(der
[punt
++]&0x7F);
134 /* wrapper around, and no bignums... */
135 return ASN1_DER_ERROR
;
147 * asn1_get_octet_der:
148 * @der: DER data to decode containing the OCTET SEQUENCE.
149 * @der_len: Length of DER data to decode.
150 * @ret_len: Output variable containing the length of the DER data.
151 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
152 * @str_size: Length of pre-allocated output buffer.
153 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
155 * Extract an OCTET SEQUENCE from DER data.
157 * Return value: Returns ASN1_SUCCESS on success, or an error.
160 asn1_get_octet_der(const unsigned char *der
, int der_len
,
161 int *ret_len
,unsigned char *str
, int str_size
, int *str_len
)
165 if (der_len
<= 0) return ASN1_GENERIC_ERROR
;
167 /* if(str==NULL) return ASN1_SUCCESS; */
168 *str_len
=asn1_get_length_der(der
, der_len
, &len_len
);
171 return ASN1_DER_ERROR
;
173 *ret_len
=*str_len
+len_len
;
174 if ( str_size
>= *str_len
)
175 memcpy(str
,der
+len_len
,*str_len
);
177 return ASN1_MEM_ERROR
;
185 /* Returns ASN1_SUCCESS on success or an error code on error.
188 _asn1_get_time_der(const unsigned char *der
, int der_len
, int *ret_len
,unsigned char *str
,int str_size
)
192 if(der_len
<=0 || str
==NULL
) return ASN1_DER_ERROR
;
193 str_len
=asn1_get_length_der(der
, der_len
, &len_len
);
194 if (str_len
< 0 || str_size
< str_len
)
195 return ASN1_DER_ERROR
;
196 memcpy(str
,der
+len_len
,str_len
);
198 *ret_len
=str_len
+len_len
;
206 _asn1_get_objectid_der(const unsigned char *der
,int der_len
, int *ret_len
,unsigned char *str
, int str_size
)
210 unsigned long val
,val1
;
213 if (str
&& str_size
> 0) str
[0] = 0; /* no oid */
215 if(str
==NULL
|| der_len
<= 0) return;
216 len
=asn1_get_length_der(der
,der_len
, &len_len
);
218 if (len
< 0 || len
> der_len
|| len_len
> der_len
) return;
220 val1
=der
[len_len
]/40;
221 val
=der
[len_len
]-val1
*40;
223 _asn1_str_cpy(str
, str_size
, _asn1_ltostr(val1
,temp
));
224 _asn1_str_cat(str
, str_size
, ".");
225 _asn1_str_cat(str
, str_size
, _asn1_ltostr(val
,temp
));
230 val
|=der
[len_len
+k
]&0x7F;
231 if(!(der
[len_len
+k
]&0x80)){
232 _asn1_str_cat(str
, str_size
,".");
233 _asn1_str_cat(str
, str_size
,_asn1_ltostr(val
,temp
));
237 *ret_len
=len
+len_len
;
244 asn1_get_bit_der(const unsigned char *der
, int der_len
,
245 int *ret_len
,unsigned char *str
, int str_size
, int *bit_len
)
247 int len_len
,len_byte
;
249 if (der_len
<=0) return ASN1_GENERIC_ERROR
;
250 len_byte
=asn1_get_length_der(der
,der_len
,&len_len
)-1;
252 return ASN1_DER_ERROR
;
254 *ret_len
=len_byte
+len_len
+1;
255 *bit_len
=len_byte
*8-der
[len_len
];
257 if (str_size
>= len_byte
)
258 memcpy(str
,der
+len_len
+1,len_byte
);
260 return ASN1_MEM_ERROR
;
270 _asn1_extract_tag_der(node_asn
*node
,const unsigned char *der
, int der_len
,int *ret_len
)
273 int counter
,len2
,len3
,is_tag_implicit
;
274 unsigned long tag
,tag_implicit
=0;
275 unsigned char class,class2
,class_implicit
=0;
277 if (der_len
<= 0) return ASN1_GENERIC_ERROR
;
279 counter
=is_tag_implicit
=0;
281 if(node
->type
&CONST_TAG
){
284 if(type_field(p
->type
)==TYPE_TAG
){
285 if(p
->type
&CONST_APPLICATION
) class2
=APPLICATION
;
286 else if(p
->type
&CONST_UNIVERSAL
) class2
=UNIVERSAL
;
287 else if(p
->type
&CONST_PRIVATE
) class2
=PRIVATE
;
288 else class2
=CONTEXT_SPECIFIC
;
290 if(p
->type
&CONST_EXPLICIT
){
291 if (asn1_get_tag_der(der
+counter
, der_len
-counter
,&class,&len2
, &tag
)!=ASN1_SUCCESS
)
292 return ASN1_DER_ERROR
;
293 if (counter
+len2
> der_len
)
294 return ASN1_DER_ERROR
;
296 len3
=asn1_get_length_der(der
+counter
,der_len
-counter
, &len2
);
298 return ASN1_DER_ERROR
;
300 if(!is_tag_implicit
){
301 if((class!=(class2
|STRUCTURED
)) || (tag
!=strtoul(p
->value
,NULL
,10)))
302 return ASN1_TAG_ERROR
;
304 else{ /* TAG_IMPLICIT */
305 if((class!=class_implicit
) || (tag
!=tag_implicit
))
306 return ASN1_TAG_ERROR
;
311 else{ /* TAG_IMPLICIT */
312 if(!is_tag_implicit
){
313 if((type_field(node
->type
)==TYPE_SEQUENCE
) ||
314 (type_field(node
->type
)==TYPE_SEQUENCE_OF
) ||
315 (type_field(node
->type
)==TYPE_SET
) ||
316 (type_field(node
->type
)==TYPE_SET_OF
)) class2
|=STRUCTURED
;
317 class_implicit
=class2
;
318 tag_implicit
=strtoul(p
->value
,NULL
,10);
328 if (asn1_get_tag_der(der
+counter
, der_len
-counter
,&class,&len2
, &tag
)!=ASN1_SUCCESS
)
329 return ASN1_DER_ERROR
;
330 if (counter
+len2
> der_len
)
331 return ASN1_DER_ERROR
;
333 if((class!=class_implicit
) || (tag
!=tag_implicit
)){
334 if(type_field(node
->type
)==TYPE_OCTET_STRING
){
335 class_implicit
|= STRUCTURED
;
336 if((class!=class_implicit
) || (tag
!=tag_implicit
))
337 return ASN1_TAG_ERROR
;
340 return ASN1_TAG_ERROR
;
344 if(type_field(node
->type
)==TYPE_TAG
){
350 if (asn1_get_tag_der(der
+counter
, der_len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
351 return ASN1_DER_ERROR
;
352 if (counter
+len2
> der_len
)
353 return ASN1_DER_ERROR
;
355 switch(type_field(node
->type
)){
357 if((class!=UNIVERSAL
) || (tag
!=TAG_NULL
)) return ASN1_DER_ERROR
;
360 if((class!=UNIVERSAL
) || (tag
!=TAG_BOOLEAN
)) return ASN1_DER_ERROR
;
363 if((class!=UNIVERSAL
) || (tag
!=TAG_INTEGER
)) return ASN1_DER_ERROR
;
365 case TYPE_ENUMERATED
:
366 if((class!=UNIVERSAL
) || (tag
!=TAG_ENUMERATED
)) return ASN1_DER_ERROR
;
369 if((class!=UNIVERSAL
) || (tag
!=TAG_OBJECT_ID
)) return ASN1_DER_ERROR
;
372 if(node
->type
&CONST_UTC
){
373 if((class!=UNIVERSAL
) || (tag
!=TAG_UTCTime
)) return ASN1_DER_ERROR
;
376 if((class!=UNIVERSAL
) || (tag
!=TAG_GENERALIZEDTime
))
377 return ASN1_DER_ERROR
;
380 case TYPE_OCTET_STRING
:
381 if(((class!=UNIVERSAL
) && (class!=(UNIVERSAL
|STRUCTURED
)))
382 || (tag
!=TAG_OCTET_STRING
)) return ASN1_DER_ERROR
;
384 case TYPE_GENERALSTRING
:
385 if((class!=UNIVERSAL
) || (tag
!=TAG_GENERALSTRING
)) return ASN1_DER_ERROR
;
387 case TYPE_BIT_STRING
:
388 if((class!=UNIVERSAL
) || (tag
!=TAG_BIT_STRING
)) return ASN1_DER_ERROR
;
390 case TYPE_SEQUENCE
: case TYPE_SEQUENCE_OF
:
391 if((class!=(UNIVERSAL
|STRUCTURED
)) || (tag
!=TAG_SEQUENCE
))
392 return ASN1_DER_ERROR
;
394 case TYPE_SET
: case TYPE_SET_OF
:
395 if((class!=(UNIVERSAL
|STRUCTURED
)) || (tag
!=TAG_SET
))
396 return ASN1_DER_ERROR
;
402 return ASN1_DER_ERROR
;
414 _asn1_delete_not_used(node_asn
*node
)
418 if(node
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
422 if(p
->type
&CONST_NOT_USED
){
425 p2
=_asn1_find_left(p
);
426 if(!p2
) p2
=_asn1_find_up(p
);
428 asn1_delete_structure(&p
);
432 if(!p
) break; /* reach node */
439 else if(p
->right
) p
=p
->right
;
460 _asn1_get_octet_string(const unsigned char* der
, node_asn
*node
,int* len
)
462 int len2
,len3
,counter
,counter2
,counter_end
,tot_len
,indefinite
;
467 if(*(der
-1) & STRUCTURED
){
469 indefinite
=asn1_get_length_der(der
, *len
, &len3
);
471 return ASN1_DER_ERROR
;
474 if(indefinite
>=0) indefinite
+=len3
;
477 if(counter
>(*len
)) return ASN1_DER_ERROR
;
480 if((der
[counter
]==0) && (der
[counter
+1]==0)){
485 else if(counter
>=indefinite
) break;
487 if(der
[counter
] != TAG_OCTET_STRING
) return ASN1_DER_ERROR
;
491 len2
=asn1_get_length_der(der
+counter
,*len
-counter
, &len3
);
492 if(len2
<= 0) return ASN1_DER_ERROR
;
500 asn1_length_der(tot_len
,NULL
,&len2
);
501 temp
=(unsigned char *)_asn1_alloca(len2
+tot_len
);
503 return ASN1_MEM_ALLOC_ERROR
;
506 asn1_length_der(tot_len
,temp
,&len2
);
509 len2
=asn1_get_length_der(der
,*len
,&len3
);
510 if(len2
< -1) return ASN1_DER_ERROR
;
513 if(indefinite
==-1) counter_end
=counter
-2;
514 else counter_end
=counter
;
516 while(counter2
<counter_end
){
517 len2
=asn1_get_length_der(der
+counter2
, *len
-counter
, &len3
);
518 if(len2
< -1) return ASN1_DER_ERROR
;
520 /* FIXME: to be checked. Is this ok? Has the
521 * size been checked before?
523 memcpy(temp2
,der
+counter2
+len3
,len2
);
525 counter2
+=len2
+len3
+1;
528 _asn1_set_value(node
,temp
,tot_len
);
532 else{ /* NOT STRUCTURED */
533 len2
=asn1_get_length_der(der
, *len
, &len3
);
534 if(len2
< 0) return ASN1_DER_ERROR
;
535 if (len3
+len2
> *len
) return ASN1_DER_ERROR
;
537 _asn1_set_value(node
,der
,len3
+len2
);
548 _asn1_get_indefinite_length_string(const unsigned char* der
, int* len
)
550 int len2
,len3
,counter
,indefinite
;
554 counter
=indefinite
=0;
557 if((*len
)<counter
) return ASN1_DER_ERROR
;
559 if((der
[counter
]==0) && (der
[counter
+1]==0)){
562 if(indefinite
<=0) break;
566 if(asn1_get_tag_der(der
+counter
, *len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
567 return ASN1_DER_ERROR
;
568 if (counter
+len2
> *len
)
569 return ASN1_DER_ERROR
;
571 len2
=asn1_get_length_der(der
+counter
, *len
-counter
,&len3
);
572 if(len2
< -1) return ASN1_DER_ERROR
;
589 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
590 * @element: pointer to an ASN1 structure.
591 * @ider: vector that contains the DER encoding.
592 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
593 * @errorDescription: null-terminated string contains details when an
596 * Fill the structure *ELEMENT with values of a DER encoding
597 * string. The sructure must just be created with function
598 * 'create_stucture'. If an error occurs during the decoding
599 * procedure, the *ELEMENT is deleted and set equal to
604 * ASN1_SUCCESS: DER encoding OK.
606 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY.
608 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
609 * the structure NAME. *ELEMENT deleted.
613 asn1_der_decoding(ASN1_TYPE
*element
,const void *ider
,int len
,
614 char *errorDescription
)
616 node_asn
*node
,*p
,*p2
,*p3
;
618 int counter
,len2
,len3
,len4
,move
,ris
,tlen
;
619 unsigned char class,*temp2
;
621 int indefinite
, result
;
622 const unsigned char* der
= ider
;
626 if(node
==ASN1_TYPE_EMPTY
) return ASN1_ELEMENT_NOT_FOUND
;
628 if(node
->type
&CONST_OPTION
){
629 asn1_delete_structure(element
);
630 return ASN1_GENERIC_ERROR
;
639 if(p
->type
&CONST_SET
){
641 len2
=strtol(p2
->value
,NULL
,10);
643 if(!der
[counter
] && !der
[counter
+1]){
650 else if(counter
==len2
){
655 else if(counter
>len2
){
656 asn1_delete_structure(element
);
657 return ASN1_DER_ERROR
;
661 if((p2
->type
&CONST_SET
) && (p2
->type
&CONST_NOT_USED
)){
662 if(type_field(p2
->type
)!=TYPE_CHOICE
)
663 ris
=_asn1_extract_tag_der(p2
,der
+counter
,len
-counter
, &len2
);
667 ris
=_asn1_extract_tag_der(p3
,der
+counter
,len
-counter
, &len2
);
668 if(ris
==ASN1_SUCCESS
) break;
672 if(ris
==ASN1_SUCCESS
){
673 p2
->type
&=~CONST_NOT_USED
;
681 asn1_delete_structure(element
);
682 return ASN1_DER_ERROR
;
686 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
688 len2
=strtol(p2
->value
,NULL
,10);
696 if(p
->type
&CONST_OPTION
) asn1_delete_structure(&p
);
703 if(type_field(p
->type
)==TYPE_CHOICE
){
706 ris
=_asn1_extract_tag_der(p
->down
,der
+counter
,len
-counter
,&len2
);
709 if(ris
==ASN1_SUCCESS
){
710 while(p
->down
->right
){
712 asn1_delete_structure(&p2
);
716 else if(ris
==ASN1_ERROR_TYPE_ANY
){
717 asn1_delete_structure(element
);
718 return ASN1_ERROR_TYPE_ANY
;
722 asn1_delete_structure(&p2
);
727 if(!(p
->type
&CONST_OPTION
)){
728 asn1_delete_structure(element
);
729 return ASN1_DER_ERROR
;
736 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
738 len2
=strtol(p2
->value
,NULL
,10);
739 if((len2
!=-1) && (counter
>len2
)) ris
=ASN1_TAG_ERROR
;
742 if(ris
==ASN1_SUCCESS
) ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
743 if(ris
!=ASN1_SUCCESS
){
744 if(p
->type
&CONST_OPTION
){
745 p
->type
|=CONST_NOT_USED
;
748 else if(p
->type
&CONST_DEFAULT
) {
749 _asn1_set_value(p
,NULL
,0);
753 if (errorDescription
!=NULL
)
754 _asn1_error_description_tag_error(p
,errorDescription
);
756 asn1_delete_structure(element
);
757 return ASN1_TAG_ERROR
;
763 if(ris
==ASN1_SUCCESS
){
764 switch(type_field(p
->type
)){
767 asn1_delete_structure(element
);
768 return ASN1_DER_ERROR
;
774 if(der
[counter
++]!=1){
775 asn1_delete_structure(element
);
776 return ASN1_DER_ERROR
;
778 if(der
[counter
++]==0) _asn1_set_value(p
,"F",1);
779 else _asn1_set_value(p
,"T",1);
782 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
783 len2
=asn1_get_length_der(der
+counter
,len
-counter
, &len3
);
784 if(len2
< 0) return ASN1_DER_ERROR
;
785 if (len2
+len3
> len
-counter
) return ASN1_DER_ERROR
;
786 _asn1_set_value(p
,der
+counter
,len3
+len2
);
791 _asn1_get_objectid_der(der
+counter
,len
-counter
,&len2
, temp
, sizeof(temp
));
794 _asn1_set_value(p
,temp
,tlen
+1);
799 result
= _asn1_get_time_der(der
+counter
,len
-counter
,&len2
,temp
,sizeof(temp
)-1);
800 if (result
!= ASN1_SUCCESS
) {
801 asn1_delete_structure(element
);
806 _asn1_set_value(p
,temp
,tlen
+1);
810 case TYPE_OCTET_STRING
:
812 ris
=_asn1_get_octet_string(der
+counter
,p
,&len3
);
813 if(ris
!= ASN1_SUCCESS
) return ris
;
817 case TYPE_GENERALSTRING
:
818 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
819 if(len2
< 0) return ASN1_DER_ERROR
;
820 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
821 _asn1_set_value(p
,der
+counter
,len3
+len2
);
825 case TYPE_BIT_STRING
:
826 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
827 if(len2
< 0) return ASN1_DER_ERROR
;
828 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
829 _asn1_set_value(p
,der
+counter
,len3
+len2
);
833 case TYPE_SEQUENCE
: case TYPE_SET
:
835 len2
=strtol(p
->value
,NULL
,10);
836 _asn1_set_value(p
,NULL
,0);
837 if(len2
==-1){ /* indefinite length method */
838 if (len
-counter
+1 > 0) {
839 if((der
[counter
]) || der
[counter
+1]){
840 asn1_delete_structure(element
);
841 return ASN1_DER_ERROR
;
843 } else return ASN1_DER_ERROR
;
846 else{ /* definite length method */
848 asn1_delete_structure(element
);
849 return ASN1_DER_ERROR
;
854 else{ /* move==DOWN || move==RIGHT */
855 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
856 if(len3
< -1) return ASN1_DER_ERROR
;
859 _asn1_ltostr(counter
+len3
,temp
);
862 _asn1_set_value(p
,temp
,tlen
+1);
868 if(type_field(p2
->type
)!=TYPE_TAG
){
870 asn1_delete_structure(&p2
);
878 else{ /* indefinite length method */
879 _asn1_set_value(p
,"-1",3);
884 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
886 len2
=strtol(p
->value
,NULL
,10);
887 if(len2
==-1){ /* indefinite length method */
888 if((counter
+2)>len
) return ASN1_DER_ERROR
;
889 if((der
[counter
]) || der
[counter
+1]){
890 _asn1_append_sequence_set(p
);
892 while(p
->right
) p
=p
->right
;
896 _asn1_set_value(p
,NULL
,0);
899 else{ /* definite length method */
901 _asn1_append_sequence_set(p
);
903 while(p
->right
) p
=p
->right
;
907 _asn1_set_value(p
,NULL
,0);
909 asn1_delete_structure(element
);
910 return ASN1_DER_ERROR
;
914 else{ /* move==DOWN || move==RIGHT */
915 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
916 if(len3
< -1) return ASN1_DER_ERROR
;
919 if(len3
>0){ /* definite length method */
920 _asn1_ltostr(counter
+len3
,temp
);
924 _asn1_set_value(p
,temp
,tlen
+1);
926 else { /* indefinite length method */
927 _asn1_set_value(p
,"-1",3);
930 while((type_field(p2
->type
)==TYPE_TAG
) || (type_field(p2
->type
)==TYPE_SIZE
)) p2
=p2
->right
;
931 if(p2
->right
==NULL
) _asn1_append_sequence_set(p
);
938 if(asn1_get_tag_der(der
+counter
,len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
939 return ASN1_DER_ERROR
;
940 if (counter
+len2
> len
)
941 return ASN1_DER_ERROR
;
942 len4
=asn1_get_length_der(der
+counter
+len2
,len
-counter
-len2
,&len3
);
943 if(len4
< -1) return ASN1_DER_ERROR
;
944 if(len4
> len
-counter
+len2
+len3
) return ASN1_DER_ERROR
;
947 asn1_length_der(len2
+len3
,NULL
,&len4
);
948 temp2
=(unsigned char *)_asn1_alloca(len2
+len3
+len4
);
950 asn1_delete_structure(element
);
951 return ASN1_MEM_ALLOC_ERROR
;
954 asn1_octet_der(der
+counter
,len2
+len3
,temp2
,&len4
);
955 _asn1_set_value(p
,temp2
,len4
);
959 else{ /* indefinite length */
960 /* Check indefinite lenth method in an EXPLICIT TAG */
961 if((p
->type
&CONST_TAG
) && (der
[counter
-1]==0x80))
967 ris
=_asn1_get_indefinite_length_string(der
+counter
,&len2
);
968 if(ris
!= ASN1_SUCCESS
){
969 asn1_delete_structure(element
);
972 asn1_length_der(len2
,NULL
,&len4
);
973 temp2
=(unsigned char *)_asn1_alloca(len2
+len4
);
975 asn1_delete_structure(element
);
976 return ASN1_MEM_ALLOC_ERROR
;
979 asn1_octet_der(der
+counter
,len2
,temp2
,&len4
);
980 _asn1_set_value(p
,temp2
,len4
);
984 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
985 an indefinite length method. */
987 if(!der
[counter
] && !der
[counter
+1]){
991 asn1_delete_structure(element
);
992 return ASN1_DER_ERROR
;
999 move
=(move
==UP
)?RIGHT
:DOWN
;
1004 if(p
==node
&& move
!=DOWN
) break;
1007 if(p
->down
) p
=p
->down
;
1010 if((move
==RIGHT
) && !(p
->type
&CONST_SET
)){
1011 if(p
->right
) p
=p
->right
;
1014 if(move
==UP
) p
=_asn1_find_up(p
);
1017 _asn1_delete_not_used(*element
);
1020 asn1_delete_structure(element
);
1021 return ASN1_DER_ERROR
;
1024 return ASN1_SUCCESS
;
1029 #define SAME_BRANCH 2
1030 #define OTHER_BRANCH 3
1034 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
1035 * @structure: pointer to an ASN1 structure
1036 * @elementName: name of the element to fill
1037 * @ider: vector that contains the DER encoding of the whole structure.
1038 * @len: number of bytes of *der: der[0]..der[len-1]
1039 * @errorDescription: null-terminated string contains details when an
1042 * Fill the element named ELEMENTNAME with values of a DER encoding
1043 * string. The sructure must just be created with function
1044 * 'create_stucture'. The DER vector must contain the encoding
1045 * string of the whole STRUCTURE. If an error occurs during the
1046 * decoding procedure, the *STRUCTURE is deleted and set equal to
1051 * ASN1_SUCCESS: DER encoding OK.
1053 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or
1054 * elementName == NULL.
1056 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
1057 * the structure STRUCTURE. *ELEMENT deleted.
1061 asn1_der_decoding_element(ASN1_TYPE
*structure
,const char *elementName
,
1062 const void *ider
,int len
,char *errorDescription
)
1064 node_asn
*node
,*p
,*p2
,*p3
,*nodeFound
=ASN1_TYPE_EMPTY
;
1065 char temp
[128],currentName
[MAX_NAME_SIZE
*10],*dot_p
,*char_p
;
1066 int nameLen
=MAX_NAME_SIZE
*10-1,state
;
1067 int counter
,len2
,len3
,len4
,move
,ris
, tlen
;
1068 unsigned char class,*temp2
;
1070 int indefinite
, result
;
1071 const unsigned char* der
= ider
;
1075 if(node
==ASN1_TYPE_EMPTY
) return ASN1_ELEMENT_NOT_FOUND
;
1077 if(elementName
== NULL
){
1078 asn1_delete_structure(structure
);
1079 return ASN1_ELEMENT_NOT_FOUND
;
1082 if(node
->type
&CONST_OPTION
){
1083 asn1_delete_structure(structure
);
1084 return ASN1_GENERIC_ERROR
;
1087 if((*structure
)->name
){ /* Has *structure got a name? */
1088 nameLen
-=strlen((*structure
)->name
);
1089 if(nameLen
>0) strcpy(currentName
,(*structure
)->name
);
1091 asn1_delete_structure(structure
);
1092 return ASN1_MEM_ERROR
;
1094 if(!(strcmp(currentName
,elementName
))){
1096 nodeFound
=*structure
;
1098 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1103 else{ /* *structure doesn't have a name? */
1105 if(elementName
[0]==0){
1107 nodeFound
=*structure
;
1122 if(p
->type
&CONST_SET
){
1123 p2
=_asn1_find_up(p
);
1124 len2
=strtol(p2
->value
,NULL
,10);
1130 else if(counter
>len2
){
1131 asn1_delete_structure(structure
);
1132 return ASN1_DER_ERROR
;
1136 if((p2
->type
&CONST_SET
) && (p2
->type
&CONST_NOT_USED
)){
1137 if(type_field(p2
->type
)!=TYPE_CHOICE
)
1138 ris
=_asn1_extract_tag_der(p2
,der
+counter
,len
-counter
,&len2
);
1142 ris
=_asn1_extract_tag_der(p3
,der
+counter
,len
-counter
,&len2
);
1143 if(ris
==ASN1_SUCCESS
) break;
1147 if(ris
==ASN1_SUCCESS
){
1148 p2
->type
&=~CONST_NOT_USED
;
1156 asn1_delete_structure(structure
);
1157 return ASN1_DER_ERROR
;
1161 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
1162 p2
=_asn1_find_up(p
);
1163 len2
=strtol(p2
->value
,NULL
,10);
1171 if(p
->type
&CONST_OPTION
) asn1_delete_structure(&p
);
1178 if(type_field(p
->type
)==TYPE_CHOICE
){
1181 ris
=_asn1_extract_tag_der(p
->down
,der
+counter
,len
-counter
,&len2
);
1184 if(ris
==ASN1_SUCCESS
){
1185 while(p
->down
->right
){
1187 asn1_delete_structure(&p2
);
1191 else if(ris
==ASN1_ERROR_TYPE_ANY
){
1192 asn1_delete_structure(structure
);
1193 return ASN1_ERROR_TYPE_ANY
;
1197 asn1_delete_structure(&p2
);
1202 if(!(p
->type
&CONST_OPTION
)){
1203 asn1_delete_structure(structure
);
1204 return ASN1_DER_ERROR
;
1211 if((p
->type
&CONST_OPTION
) || (p
->type
&CONST_DEFAULT
)){
1212 p2
=_asn1_find_up(p
);
1213 len2
=strtol(p2
->value
,NULL
,10);
1214 if(counter
>len2
) ris
=ASN1_TAG_ERROR
;
1217 if(ris
==ASN1_SUCCESS
) ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
1218 if(ris
!=ASN1_SUCCESS
){
1219 if(p
->type
&CONST_OPTION
){
1220 p
->type
|=CONST_NOT_USED
;
1223 else if(p
->type
&CONST_DEFAULT
) {
1224 _asn1_set_value(p
,NULL
,0);
1228 if (errorDescription
!=NULL
)
1229 _asn1_error_description_tag_error(p
,errorDescription
);
1231 asn1_delete_structure(structure
);
1232 return ASN1_TAG_ERROR
;
1238 if(ris
==ASN1_SUCCESS
){
1239 switch(type_field(p
->type
)){
1242 asn1_delete_structure(structure
);
1243 return ASN1_DER_ERROR
;
1246 if(p
==nodeFound
) state
=EXIT
;
1252 if(der
[counter
++]!=1){
1253 asn1_delete_structure(structure
);
1254 return ASN1_DER_ERROR
;
1258 if(der
[counter
++]==0) _asn1_set_value(p
,"F",1);
1259 else _asn1_set_value(p
,"T",1);
1261 if(p
==nodeFound
) state
=EXIT
;
1269 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
1270 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1271 if(len2
< 0) return ASN1_DER_ERROR
;
1273 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
1274 _asn1_set_value(p
,der
+counter
,len3
+len2
);
1276 if(p
==nodeFound
) state
=EXIT
;
1281 case TYPE_OBJECT_ID
:
1283 _asn1_get_objectid_der(der
+counter
,len
-counter
,&len2
, temp
, sizeof(temp
));
1284 tlen
= strlen(temp
);
1287 _asn1_set_value(p
,temp
,tlen
+1);
1289 if(p
==nodeFound
) state
=EXIT
;
1292 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1293 if(len2
< 0) return ASN1_DER_ERROR
;
1302 result
= _asn1_get_time_der(der
+counter
,len
-counter
,&len2
,temp
,sizeof(temp
)-1);
1303 if (result
!= ASN1_SUCCESS
) {
1304 asn1_delete_structure(structure
);
1308 tlen
= strlen(temp
);
1310 _asn1_set_value(p
,temp
,tlen
+1);
1312 if(p
==nodeFound
) state
=EXIT
;
1315 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1316 if(len2
< 0) return ASN1_DER_ERROR
;
1323 case TYPE_OCTET_STRING
:
1326 ris
=_asn1_get_octet_string(der
+counter
,p
,&len3
);
1327 if(p
==nodeFound
) state
=EXIT
;
1330 ris
=_asn1_get_octet_string(der
+counter
,NULL
,&len3
);
1332 if(ris
!= ASN1_SUCCESS
) return ris
;
1336 case TYPE_GENERALSTRING
:
1337 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1338 if(len2
< 0) return ASN1_DER_ERROR
;
1340 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
1341 _asn1_set_value(p
,der
+counter
,len3
+len2
);
1343 if(p
==nodeFound
) state
=EXIT
;
1348 case TYPE_BIT_STRING
:
1349 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1350 if(len2
< 0) return ASN1_DER_ERROR
;
1352 if (len3
+len2
> len
-counter
) return ASN1_DER_ERROR
;
1353 _asn1_set_value(p
,der
+counter
,len3
+len2
);
1355 if(p
==nodeFound
) state
=EXIT
;
1360 case TYPE_SEQUENCE
: case TYPE_SET
:
1362 len2
=strtol(p
->value
,NULL
,10);
1363 _asn1_set_value(p
,NULL
,0);
1364 if(len2
==-1){ /* indefinite length method */
1365 if((der
[counter
]) || der
[counter
+1]){
1366 asn1_delete_structure(structure
);
1367 return ASN1_DER_ERROR
;
1371 else{ /* definite length method */
1373 asn1_delete_structure(structure
);
1374 return ASN1_DER_ERROR
;
1377 if(p
==nodeFound
) state
=EXIT
;
1380 else{ /* move==DOWN || move==RIGHT */
1381 if(state
==OTHER_BRANCH
){
1382 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1383 if(len3
< 0) return ASN1_DER_ERROR
;
1387 else { /* state==SAME_BRANCH or state==FOUND */
1388 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1389 if(len3
< 0) return ASN1_DER_ERROR
;
1392 _asn1_ltostr(counter
+len3
,temp
);
1393 tlen
= strlen(temp
);
1396 _asn1_set_value(p
,temp
,tlen
+1);
1402 if(type_field(p2
->type
)!=TYPE_TAG
){
1404 asn1_delete_structure(&p2
);
1412 else{ /* indefinite length method */
1413 _asn1_set_value(p
,"-1",3);
1419 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
1421 len2
=strtol(p
->value
,NULL
,10);
1423 _asn1_append_sequence_set(p
);
1425 while(p
->right
) p
=p
->right
;
1429 _asn1_set_value(p
,NULL
,0);
1431 asn1_delete_structure(structure
);
1432 return ASN1_DER_ERROR
;
1435 if(p
==nodeFound
) state
=EXIT
;
1437 else{ /* move==DOWN || move==RIGHT */
1438 if(state
==OTHER_BRANCH
){
1439 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1440 if(len3
< 0) return ASN1_DER_ERROR
;
1444 else{ /* state==FOUND or state==SAME_BRANCH */
1445 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1446 if(len3
< 0) return ASN1_DER_ERROR
;
1449 _asn1_ltostr(counter
+len3
,temp
);
1450 tlen
= strlen(temp
);
1453 _asn1_set_value(p
,temp
,tlen
+1);
1455 while((type_field(p2
->type
)==TYPE_TAG
) || (type_field(p2
->type
)==TYPE_SIZE
)) p2
=p2
->right
;
1456 if(p2
->right
==NULL
) _asn1_append_sequence_set(p
);
1465 if(asn1_get_tag_der(der
+counter
, len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
1466 return ASN1_DER_ERROR
;
1467 if (counter
+len2
> len
)
1468 return ASN1_DER_ERROR
;
1470 len4
=asn1_get_length_der(der
+counter
+len2
,len
-counter
-len2
,&len3
);
1471 if(len4
< -1) return ASN1_DER_ERROR
;
1476 asn1_length_der(len2
+len3
,NULL
,&len4
);
1477 temp2
=(unsigned char *)_asn1_alloca(len2
+len3
+len4
);
1479 asn1_delete_structure(structure
);
1480 return ASN1_MEM_ALLOC_ERROR
;
1483 asn1_octet_der(der
+counter
,len2
+len3
,temp2
,&len4
);
1484 _asn1_set_value(p
,temp2
,len4
);
1487 if(p
==nodeFound
) state
=EXIT
;
1491 else{ /* indefinite length */
1492 /* Check indefinite lenth method in an EXPLICIT TAG */
1493 if((p
->type
&CONST_TAG
) && (der
[counter
-1]==0x80))
1499 ris
=_asn1_get_indefinite_length_string(der
+counter
,&len2
);
1500 if(ris
!= ASN1_SUCCESS
){
1501 asn1_delete_structure(structure
);
1506 asn1_length_der(len2
,NULL
,&len4
);
1507 temp2
=(unsigned char *)_asn1_alloca(len2
+len4
);
1509 asn1_delete_structure(structure
);
1510 return ASN1_MEM_ALLOC_ERROR
;
1513 asn1_octet_der(der
+counter
,len2
,temp2
,&len4
);
1514 _asn1_set_value(p
,temp2
,len4
);
1517 if(p
==nodeFound
) state
=EXIT
;
1522 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1523 an indefinite length method. */
1525 if(!der
[counter
] && !der
[counter
+1]){
1529 asn1_delete_structure(structure
);
1530 return ASN1_DER_ERROR
;
1538 move
=(move
==UP
)?RIGHT
:DOWN
;
1543 if((p
==node
&& move
!=DOWN
) || (state
==EXIT
)) break;
1550 nameLen
-=strlen(p
->name
)+1;
1552 if(currentName
[0]) strcat(currentName
,".");
1553 strcat(currentName
,p
->name
);
1556 asn1_delete_structure(structure
);
1557 return ASN1_MEM_ERROR
;
1559 if(!(strcmp(currentName
,elementName
))){
1563 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1572 if((move
==RIGHT
) && !(p
->type
&CONST_SET
)){
1577 dot_p
=char_p
=currentName
;
1578 while((char_p
=strchr(char_p
,'.'))){
1583 nameLen
+=strlen(currentName
)-(dot_p
-currentName
);
1586 nameLen
-=strlen(p
->name
);
1587 if(nameLen
>0) strcat(currentName
,p
->name
);
1589 asn1_delete_structure(structure
);
1590 return ASN1_MEM_ERROR
;
1593 if(!(strcmp(currentName
,elementName
))){
1597 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1610 dot_p
=char_p
=currentName
;
1611 while((char_p
=strchr(char_p
,'.'))){
1616 nameLen
+=strlen(currentName
)-(dot_p
-currentName
);
1619 if(!(strcmp(currentName
,elementName
))){
1623 else if(!memcmp(currentName
,elementName
,strlen(currentName
)))
1631 _asn1_delete_not_used(*structure
);
1634 asn1_delete_structure(structure
);
1635 return ASN1_DER_ERROR
;
1638 return ASN1_SUCCESS
;
1644 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1645 * @element: pointer to an ASN1 element
1646 * @ider: vector that contains the DER encoding.
1647 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
1648 * @name_element: an element of NAME structure.
1649 * @start: the position of the first byte of NAME_ELEMENT decoding
1651 * @end: the position of the last byte of NAME_ELEMENT decoding
1654 * Find the start and end point of an element in a DER encoding
1655 * string. I mean that if you have a der encoding and you have
1656 * already used the function "asn1_der_decoding" to fill a structure,
1657 * it may happen that you want to find the piece of string concerning
1658 * an element of the structure.
1660 * Example: the sequence "tbsCertificate" inside an X509 certificate.
1664 * ASN1_SUCCESS: DER encoding OK.
1666 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or
1667 * NAME_ELEMENT is not a valid element.
1669 * ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match
1670 * the structure ELEMENT.
1674 asn1_der_decoding_startEnd(ASN1_TYPE element
,const void *ider
,int len
,
1675 const char *name_element
,int *start
, int *end
)
1677 node_asn
*node
,*node_to_find
,*p
,*p2
,*p3
;
1678 int counter
,len2
,len3
,len4
,move
,ris
;
1679 unsigned char class;
1682 const unsigned char* der
= ider
;
1686 if(node
==ASN1_TYPE_EMPTY
) return ASN1_ELEMENT_NOT_FOUND
;
1688 node_to_find
=_asn1_find_node(node
,name_element
);
1690 if(node_to_find
==NULL
) return ASN1_ELEMENT_NOT_FOUND
;
1692 if(node_to_find
==node
){
1695 return ASN1_SUCCESS
;
1698 if(node
->type
&CONST_OPTION
) return ASN1_GENERIC_ERROR
;
1707 if(p
->type
&CONST_SET
){
1708 p2
=_asn1_find_up(p
);
1709 len2
=strtol(p2
->value
,NULL
,10);
1711 if(!der
[counter
] && !der
[counter
+1]){
1718 else if(counter
==len2
){
1723 else if(counter
>len2
) return ASN1_DER_ERROR
;
1726 if((p2
->type
&CONST_SET
) && (p2
->type
&CONST_NOT_USED
)){ /* CONTROLLARE */
1727 if(type_field(p2
->type
)!=TYPE_CHOICE
)
1728 ris
=_asn1_extract_tag_der(p2
,der
+counter
,len
-counter
,&len2
);
1731 ris
=_asn1_extract_tag_der(p3
,der
+counter
,len
-counter
,&len2
);
1733 if(ris
==ASN1_SUCCESS
){
1734 p2
->type
&=~CONST_NOT_USED
;
1741 if(p2
==NULL
) return ASN1_DER_ERROR
;
1744 if(p
==node_to_find
) *start
=counter
;
1746 if(type_field(p
->type
)==TYPE_CHOICE
){
1748 ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
1749 if(p
==node_to_find
) *start
=counter
;
1752 if(ris
==ASN1_SUCCESS
) ris
=_asn1_extract_tag_der(p
,der
+counter
,len
-counter
,&len2
);
1753 if(ris
!=ASN1_SUCCESS
){
1754 if(p
->type
&CONST_OPTION
){
1755 p
->type
|=CONST_NOT_USED
;
1758 else if(p
->type
&CONST_DEFAULT
) {
1762 return ASN1_TAG_ERROR
;
1768 if(ris
==ASN1_SUCCESS
){
1769 switch(type_field(p
->type
)){
1771 if(der
[counter
]) return ASN1_DER_ERROR
;
1776 if(der
[counter
++]!=1) return ASN1_DER_ERROR
;
1780 case TYPE_INTEGER
: case TYPE_ENUMERATED
:
1781 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1782 if(len2
< 0) return ASN1_DER_ERROR
;
1786 case TYPE_OBJECT_ID
:
1787 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1788 if(len2
< 0) return ASN1_DER_ERROR
;
1793 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1794 if(len2
< 0) return ASN1_DER_ERROR
;
1798 case TYPE_OCTET_STRING
:
1800 ris
=_asn1_get_octet_string(der
+counter
,NULL
,&len3
);
1801 if(ris
!= ASN1_SUCCESS
) return ris
;
1805 case TYPE_GENERALSTRING
:
1806 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1807 if(len2
< 0) return ASN1_DER_ERROR
;
1811 case TYPE_BIT_STRING
:
1812 len2
=asn1_get_length_der(der
+counter
,len
-counter
,&len3
);
1813 if(len2
< 0) return ASN1_DER_ERROR
;
1817 case TYPE_SEQUENCE
: case TYPE_SET
:
1819 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1820 if(len3
< -1) return ASN1_DER_ERROR
;
1822 if(len3
==0) move
=RIGHT
;
1826 if(!der
[counter
] && !der
[counter
+1]) /* indefinite length method */
1831 case TYPE_SEQUENCE_OF
: case TYPE_SET_OF
:
1833 len3
=asn1_get_length_der(der
+counter
,len
-counter
,&len2
);
1834 if(len3
< -1) return ASN1_DER_ERROR
;
1836 if((len3
==-1) && !der
[counter
] && !der
[counter
+1])
1840 while((type_field(p2
->type
)==TYPE_TAG
) ||
1841 (type_field(p2
->type
)==TYPE_SIZE
)) p2
=p2
->right
;
1846 if(!der
[counter
] && !der
[counter
+1]) /* indefinite length method */
1852 if (asn1_get_tag_der(der
+counter
, len
-counter
,&class,&len2
,&tag
)!=ASN1_SUCCESS
)
1853 return ASN1_DER_ERROR
;
1854 if (counter
+len2
> len
)
1855 return ASN1_DER_ERROR
;
1857 len4
=asn1_get_length_der(der
+counter
+len2
,len
-counter
-len2
,&len3
);
1858 if(len4
< -1) return ASN1_DER_ERROR
;
1861 counter
+=len2
+len4
+len3
;
1863 else{ /* indefinite length */
1864 /* Check indefinite lenth method in an EXPLICIT TAG */
1865 if((p
->type
&CONST_TAG
) && (der
[counter
-1]==0x80))
1871 ris
=_asn1_get_indefinite_length_string(der
+counter
,&len2
);
1872 if(ris
!= ASN1_SUCCESS
)
1876 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1877 an indefinite length method. */
1879 if(!der
[counter
] && !der
[counter
+1])
1882 return ASN1_DER_ERROR
;
1888 move
=(move
==UP
)?RIGHT
:DOWN
;
1893 if((p
==node_to_find
) && (move
==RIGHT
)){
1895 return ASN1_SUCCESS
;
1898 if(p
==node
&& move
!=DOWN
) break;
1901 if(p
->down
) p
=p
->down
;
1904 if((move
==RIGHT
) && !(p
->type
&CONST_SET
)){
1905 if(p
->right
) p
=p
->right
;
1908 if(move
==UP
) p
=_asn1_find_up(p
);
1911 return ASN1_ELEMENT_NOT_FOUND
;
1916 * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure.
1917 * @definitions: ASN1 definitions
1918 * @element: pointer to an ASN1 structure
1920 * Expands every "ANY DEFINED BY" element of a structure created from
1921 * a DER decoding process (asn1_der_decoding function). The element ANY
1922 * must be defined by an OBJECT IDENTIFIER. The type used to expand
1923 * the element ANY is the first one following the definition of
1924 * the actual value of the OBJECT IDENTIFIER.
1929 * ASN1_SUCCESS: Substitution OK.
1931 * ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be
1932 * expanded due to a problem in OBJECT_ID -> TYPE association.
1934 * other errors: Result of der decoding process.
1938 asn1_expand_any_defined_by(ASN1_TYPE definitions
,ASN1_TYPE
*element
)
1940 char definitionsName
[MAX_NAME_SIZE
],name
[2*MAX_NAME_SIZE
+1],value
[MAX_NAME_SIZE
];
1941 asn1_retCode retCode
=ASN1_SUCCESS
,result
;
1943 ASN1_TYPE p
,p2
,p3
,aux
=ASN1_TYPE_EMPTY
;
1944 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
1946 if((definitions
==ASN1_TYPE_EMPTY
) || (*element
==ASN1_TYPE_EMPTY
))
1947 return ASN1_ELEMENT_NOT_FOUND
;
1949 strcpy(definitionsName
,definitions
->name
);
1950 strcat(definitionsName
,".");
1955 switch(type_field(p
->type
)){
1957 if((p
->type
&CONST_DEFINED_BY
) && (p
->value
)){
1958 /* search the "DEF_BY" element */
1960 while((p2
) && (type_field(p2
->type
)!=TYPE_CONSTANT
))
1964 retCode
=ASN1_ERROR_TYPE_ANY
;
1968 p3
=_asn1_find_up(p
);
1971 retCode
=ASN1_ERROR_TYPE_ANY
;
1977 if((p3
->name
) && !(strcmp(p3
->name
,p2
->name
))) break;
1981 if((!p3
) || (type_field(p3
->type
)!=TYPE_OBJECT_ID
) ||
1984 p3
=_asn1_find_up(p
);
1985 p3
=_asn1_find_up(p3
);
1988 retCode
=ASN1_ERROR_TYPE_ANY
;
1995 if((p3
->name
) && !(strcmp(p3
->name
,p2
->name
))) break;
1999 if((!p3
) || (type_field(p3
->type
)!=TYPE_OBJECT_ID
) ||
2001 retCode
=ASN1_ERROR_TYPE_ANY
;
2006 /* search the OBJECT_ID into definitions */
2007 p2
=definitions
->down
;
2009 if((type_field(p2
->type
)==TYPE_OBJECT_ID
) &&
2010 (p2
->type
& CONST_ASSIGN
)){
2011 strcpy(name
,definitionsName
);
2012 strcat(name
,p2
->name
);
2015 result
=asn1_read_value(definitions
,name
,value
,&len
);
2017 if((result
== ASN1_SUCCESS
) && (!strcmp(p3
->value
,value
))){
2018 p2
=p2
->right
; /* pointer to the structure to
2019 use for expansion */
2020 while((p2
) && (p2
->type
& CONST_ASSIGN
))
2024 strcpy(name
,definitionsName
);
2025 strcat(name
,p2
->name
);
2027 result
=asn1_create_element(definitions
,name
,&aux
);
2028 if(result
== ASN1_SUCCESS
){
2029 _asn1_set_name(aux
,p
->name
);
2030 len2
=asn1_get_length_der(p
->value
,p
->value_len
,&len3
);
2031 if(len2
< 0) return ASN1_DER_ERROR
;
2033 result
=asn1_der_decoding(&aux
,p
->value
+len3
,len2
,
2035 if(result
== ASN1_SUCCESS
){
2037 _asn1_set_right(aux
,p
->right
);
2038 _asn1_set_right(p
,aux
);
2040 result
=asn1_delete_structure(&p
);
2041 if(result
== ASN1_SUCCESS
){
2043 aux
=ASN1_TYPE_EMPTY
;
2046 else{ /* error with asn1_delete_structure */
2047 asn1_delete_structure(&aux
);
2052 else{/* error with asn1_der_decoding */
2057 else{/* error with asn1_create_element */
2062 else{/* error with the pointer to the structure to exapand */
2063 retCode
=ASN1_ERROR_TYPE_ANY
;
2072 retCode
=ASN1_ERROR_TYPE_ANY
;
2086 else if(p
==*element
){
2090 else if(p
->right
) p
=p
->right
;
2112 * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure.
2113 * @definitions: ASN1 definitions
2114 * @element: pointer to an ASN1 structure
2115 * @octetName: name of the OCTECT STRING field to expand.
2116 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2117 * the type for expansion.
2119 * Expands an "OCTET STRING" element of a structure created from a
2120 * DER decoding process (asn1_der_decoding function). The type used
2121 * for expansion is the first one following the definition of the
2122 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2126 * ASN1_SUCCESS: Substitution OK.
2128 * ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct.
2130 * ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use
2133 * other errors: result of der decoding process.
2136 asn1_expand_octet_string(ASN1_TYPE definitions
,ASN1_TYPE
*element
,
2137 const char *octetName
,const char *objectName
)
2139 char name
[2*MAX_NAME_SIZE
+1],value
[MAX_NAME_SIZE
];
2140 asn1_retCode retCode
=ASN1_SUCCESS
,result
;
2142 ASN1_TYPE p2
,aux
=ASN1_TYPE_EMPTY
;
2143 ASN1_TYPE octetNode
=ASN1_TYPE_EMPTY
,objectNode
=ASN1_TYPE_EMPTY
;
2144 char errorDescription
[MAX_ERROR_DESCRIPTION_SIZE
];
2146 if((definitions
==ASN1_TYPE_EMPTY
) || (*element
==ASN1_TYPE_EMPTY
))
2147 return ASN1_ELEMENT_NOT_FOUND
;
2149 octetNode
=_asn1_find_node(*element
,octetName
);
2150 if(octetNode
==ASN1_TYPE_EMPTY
)
2151 return ASN1_ELEMENT_NOT_FOUND
;
2152 if(type_field(octetNode
->type
)!=TYPE_OCTET_STRING
)
2153 return ASN1_ELEMENT_NOT_FOUND
;
2154 if(octetNode
->value
==NULL
)
2155 return ASN1_VALUE_NOT_FOUND
;
2157 objectNode
=_asn1_find_node(*element
,objectName
);
2158 if(objectNode
==ASN1_TYPE_EMPTY
)
2159 return ASN1_ELEMENT_NOT_FOUND
;
2161 if(type_field(objectNode
->type
)!=TYPE_OBJECT_ID
)
2162 return ASN1_ELEMENT_NOT_FOUND
;
2164 if(objectNode
->value
==NULL
)
2165 return ASN1_VALUE_NOT_FOUND
;
2168 /* search the OBJECT_ID into definitions */
2169 p2
=definitions
->down
;
2171 if((type_field(p2
->type
)==TYPE_OBJECT_ID
) &&
2172 (p2
->type
& CONST_ASSIGN
)){
2173 strcpy(name
,definitions
->name
);
2175 strcat(name
,p2
->name
);
2177 len
= sizeof(value
);
2178 result
=asn1_read_value(definitions
,name
,value
,&len
);
2180 if((result
== ASN1_SUCCESS
) && (!strcmp(objectNode
->value
,value
))){
2182 p2
=p2
->right
; /* pointer to the structure to
2183 use for expansion */
2184 while((p2
) && (p2
->type
& CONST_ASSIGN
))
2188 strcpy(name
,definitions
->name
);
2190 strcat(name
,p2
->name
);
2192 result
=asn1_create_element(definitions
,name
,&aux
);
2193 if(result
== ASN1_SUCCESS
){
2194 _asn1_set_name(aux
,octetNode
->name
);
2195 len2
=asn1_get_length_der(octetNode
->value
,octetNode
->value_len
,&len3
);
2196 if(len2
< 0) return ASN1_DER_ERROR
;
2198 result
=asn1_der_decoding(&aux
,octetNode
->value
+len3
,len2
,
2200 if(result
== ASN1_SUCCESS
){
2202 _asn1_set_right(aux
,octetNode
->right
);
2203 _asn1_set_right(octetNode
,aux
);
2205 result
=asn1_delete_structure(&octetNode
);
2206 if(result
== ASN1_SUCCESS
){
2207 aux
=ASN1_TYPE_EMPTY
;
2210 else{ /* error with asn1_delete_structure */
2211 asn1_delete_structure(&aux
);
2216 else{/* error with asn1_der_decoding */
2221 else{/* error with asn1_create_element */
2226 else{/* error with the pointer to the structure to exapand */
2227 retCode
=ASN1_VALUE_NOT_VALID
;
2237 if(!p2
) retCode
=ASN1_VALUE_NOT_VALID
;