Fix.
[libtasn1.git] / lib / decoding.c
blob8eafb1d81e1707308c72cc450f0a2569e8cb79fd
1 /*
2 * Copyright (C) 2002 Fabio Fiorina
3 * Copyright (C) 2004 Simon Josefsson
5 * This file is part of LIBASN1.
7 * The LIBTASN1 library is free software; you can redistribute it and/or
8 * 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,
13 * but 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 02110-1301, USA
23 /*****************************************************/
24 /* File: decoding.c */
25 /* Description: Functions to manage DER decoding */
26 /*****************************************************/
28 #include <int.h>
29 #include <errors.h>
30 #include "der.h"
31 #include "parser_aux.h"
32 #include <gstr.h>
33 #include "structure.h"
34 #include "element.h"
37 void
38 _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
41 Estrcpy(ErrorDescription,":: tag error near element '");
42 _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
43 MAX_ERROR_DESCRIPTION_SIZE-40);
44 Estrcat(ErrorDescription,"'");
49 signed long
50 _asn1_get_length_der(const unsigned char *der,int *len)
52 unsigned long ans;
53 int k,punt;
55 if(!(der[0]&128)){
56 /* short form */
57 *len=1;
58 return der[0];
60 else{
61 /* Long form */
62 k=der[0]&0x7F;
63 punt=1;
64 if(k){ /* definite length method */
65 ans=0;
66 while(punt<=k) ans=ans*256+der[punt++];
68 else{ /* indefinite length method */
69 ans=-1;
72 *len=punt;
73 return ans;
80 unsigned int
81 _asn1_get_tag_der(const unsigned char *der,unsigned char *class,int *len)
83 int punt,ris;
85 if (der==NULL || len == NULL) return ASN1_DER_ERROR;
86 *class=der[0]&0xE0;
87 if((der[0]&0x1F)!=0x1F){
88 /* short form */
89 *len=1;
90 ris=der[0]&0x1F;
92 else{
93 /* Long form */
94 punt=1;
95 ris=0;
96 while(der[punt]&128) ris=ris*128+(der[punt++]&0x7F);
97 ris=ris*128+(der[punt++]&0x7F);
98 *len=punt;
100 return ris;
107 _asn1_get_octet_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len)
109 int len_len;
111 /* if(str==NULL) return ASN1_SUCCESS; */
112 *str_len=_asn1_get_length_der(der,&len_len);
114 *der_len=*str_len+len_len;
115 if ( str_size >= *str_len)
116 memcpy(str,der+len_len,*str_len);
117 else {
118 return ASN1_MEM_ERROR;
121 return ASN1_SUCCESS;
126 /* Returns ASN1_SUCCESS on success or an error code on error.
129 _asn1_get_time_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size)
131 int len_len,str_len;
133 if(str==NULL) return ASN1_DER_ERROR;
134 str_len=_asn1_get_length_der(der,&len_len);
135 if (str_len < 0 || str_size < str_len)
136 return ASN1_DER_ERROR;
137 memcpy(str,der+len_len,str_len);
138 str[str_len]=0;
139 *der_len=str_len+len_len;
141 return ASN1_SUCCESS;
146 void
147 _asn1_get_objectid_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size)
149 int len_len,len,k;
150 char temp[20];
151 unsigned long val,val1;
153 if(str==NULL) return;
154 len=_asn1_get_length_der(der,&len_len);
156 val1=der[len_len]/40;
157 val=der[len_len]-val1*40;
159 _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
160 _asn1_str_cat(str, str_size, ".");
161 _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
163 val=0;
164 for(k=1;k<len;k++){
165 val=val<<7;
166 val|=der[len_len+k]&0x7F;
167 if(!(der[len_len+k]&0x80)){
168 _asn1_str_cat(str, str_size,".");
169 _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
170 val=0;
173 *der_len=len+len_len;
180 _asn1_get_bit_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len)
182 int len_len,len_byte;
184 len_byte=_asn1_get_length_der(der,&len_len)-1;
186 *der_len=len_byte+len_len+1;
187 *bit_len=len_byte*8-der[len_len];
189 if (str_size >= len_byte)
190 memcpy(str,der+len_len+1,len_byte);
191 else {
192 return ASN1_MEM_ERROR;
195 return ASN1_SUCCESS;
202 _asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len)
204 node_asn *p;
205 int counter,len2,len3,is_tag_implicit;
206 unsigned long tag,tag_implicit=0;
207 unsigned char class,class2,class_implicit=0;
210 counter=is_tag_implicit=0;
212 if(node->type&CONST_TAG){
213 p=node->down;
214 while(p){
215 if(type_field(p->type)==TYPE_TAG){
216 if(p->type&CONST_APPLICATION) class2=APPLICATION;
217 else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
218 else if(p->type&CONST_PRIVATE) class2=PRIVATE;
219 else class2=CONTEXT_SPECIFIC;
221 if(p->type&CONST_EXPLICIT){
222 tag=_asn1_get_tag_der(der+counter,&class,&len2);
223 counter+=len2;
224 len3=_asn1_get_length_der(der+counter,&len2);
225 counter+=len2;
226 if(!is_tag_implicit){
227 if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
228 return ASN1_TAG_ERROR;
230 else{ /* TAG_IMPLICIT */
231 if((class!=class_implicit) || (tag!=tag_implicit))
232 return ASN1_TAG_ERROR;
235 is_tag_implicit=0;
237 else{ /* TAG_IMPLICIT */
238 if(!is_tag_implicit){
239 if((type_field(node->type)==TYPE_SEQUENCE) ||
240 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
241 (type_field(node->type)==TYPE_SET) ||
242 (type_field(node->type)==TYPE_SET_OF)) class2|=STRUCTURED;
243 class_implicit=class2;
244 tag_implicit=strtoul(p->value,NULL,10);
245 is_tag_implicit=1;
249 p=p->right;
253 if(is_tag_implicit){
254 tag=_asn1_get_tag_der(der+counter,&class,&len2);
255 if((class!=class_implicit) || (tag!=tag_implicit)){
256 if(type_field(node->type)==TYPE_OCTET_STRING){
257 class_implicit |= STRUCTURED;
258 if((class!=class_implicit) || (tag!=tag_implicit))
259 return ASN1_TAG_ERROR;
261 else
262 return ASN1_TAG_ERROR;
265 else{
266 if(type_field(node->type)==TYPE_TAG){
267 counter=0;
268 *der_len=counter;
269 return ASN1_SUCCESS;
272 tag=_asn1_get_tag_der(der+counter,&class,&len2);
273 switch(type_field(node->type)){
274 case TYPE_NULL:
275 if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
276 break;
277 case TYPE_BOOLEAN:
278 if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
279 break;
280 case TYPE_INTEGER:
281 if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
282 break;
283 case TYPE_ENUMERATED:
284 if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
285 break;
286 case TYPE_OBJECT_ID:
287 if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
288 break;
289 case TYPE_TIME:
290 if(node->type&CONST_UTC){
291 if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
293 else{
294 if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime))
295 return ASN1_DER_ERROR;
297 break;
298 case TYPE_OCTET_STRING:
299 if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
300 || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
301 break;
302 case TYPE_GENERALSTRING:
303 if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
304 break;
305 case TYPE_BIT_STRING:
306 if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
307 break;
308 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
309 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE))
310 return ASN1_DER_ERROR;
311 break;
312 case TYPE_SET: case TYPE_SET_OF:
313 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET))
314 return ASN1_DER_ERROR;
315 break;
316 case TYPE_ANY:
317 counter-=len2;
318 break;
319 default:
320 return ASN1_DER_ERROR;
321 break;
325 counter+=len2;
326 *der_len=counter;
327 return ASN1_SUCCESS;
331 int
332 _asn1_delete_not_used(node_asn *node)
334 node_asn *p,*p2;
336 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
338 p=node;
339 while(p){
340 if(p->type&CONST_NOT_USED){
341 p2=NULL;
342 if(p!=node){
343 p2=_asn1_find_left(p);
344 if(!p2) p2=_asn1_find_up(p);
346 asn1_delete_structure(&p);
347 p=p2;
350 if(!p) break; /* reach node */
352 if(p->down){
353 p=p->down;
355 else{
356 if(p==node) p=NULL;
357 else if(p->right) p=p->right;
358 else{
359 while(1){
360 p=_asn1_find_up(p);
361 if(p==node){
362 p=NULL;
363 break;
365 if(p->right){
366 p=p->right;
367 break;
373 return ASN1_SUCCESS;
377 asn1_retCode
378 _asn1_get_octet_string(const unsigned char* der,node_asn *node,int* len)
380 int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
381 char *temp,*temp2;
383 counter=0;
385 if(*(der-1) & STRUCTURED){
386 tot_len=0;
387 indefinite=_asn1_get_length_der(der,&len3);
389 counter+=len3;
390 if(indefinite>=0) indefinite+=len3;
392 while(1){
393 if(counter>(*len)) return ASN1_DER_ERROR;
395 if(indefinite==-1){
396 if((der[counter]==0) && (der[counter+1]==0)){
397 counter+=2;
398 break;
401 else if(counter>=indefinite) break;
403 if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
405 counter++;
407 len2=_asn1_get_length_der(der+counter,&len3);
408 if(len2 <= 0) return ASN1_DER_ERROR;
410 counter+=len3+len2;
411 tot_len+=len2;
414 /* copy */
415 if(node){
416 _asn1_length_der(tot_len,NULL,&len2);
417 temp=(unsigned char *)_asn1_alloca(len2+tot_len);
418 if (temp==NULL){
419 return ASN1_MEM_ALLOC_ERROR;
422 _asn1_length_der(tot_len,temp,&len2);
423 tot_len+=len2;
424 temp2=temp+len2;
425 len2=_asn1_get_length_der(der,&len3);
426 counter2=len3+1;
428 if(indefinite==-1) counter_end=counter-2;
429 else counter_end=counter;
431 while(counter2<counter_end){
432 len2=_asn1_get_length_der(der+counter2,&len3);
433 memcpy(temp2,der+counter2+len3,len2);
434 temp2+=len2;
435 counter2+=len2+len3+1;
437 _asn1_set_value(node,temp,tot_len);
438 _asn1_afree(temp);
441 else{ /* NOT STRUCTURED */
442 len2=_asn1_get_length_der(der,&len3);
443 if(node)
444 _asn1_set_value(node,der,len3+len2);
445 counter=len3+len2;
448 *len=counter;
449 return ASN1_SUCCESS;
454 asn1_retCode
455 _asn1_get_indefinite_length_string(const unsigned char* der,int* len)
457 int len2,len3,counter,indefinite;
458 unsigned int tag;
459 unsigned char class;
461 counter=indefinite=0;
463 while(1){
464 if((*len)<counter) return ASN1_DER_ERROR;
466 if((der[counter]==0) && (der[counter+1]==0)){
467 counter+=2;
468 indefinite--;
469 if(indefinite<=0) break;
470 else continue;
473 tag=_asn1_get_tag_der(der+counter,&class,&len2);
474 counter+=len2;
475 len2=_asn1_get_length_der(der+counter,&len3);
476 if(len2 == -1){
477 indefinite++;
478 counter+=1;
480 else{
481 counter+=len2+len3;
485 *len=counter;
486 return ASN1_SUCCESS;
492 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
493 * @element: pointer to an ASN1 structure.
494 * @ider: vector that contains the DER encoding.
495 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
496 * @errorDescription: null-terminated string contains details when an
497 * error occurred.
499 * Fill the structure *ELEMENT with values of a DER encoding
500 * string. The sructure must just be created with function
501 * 'create_stucture'. If an error occurs during the decoding
502 * procedure, the *ELEMENT is deleted and set equal to
503 * %ASN1_TYPE_EMPTY.
505 * Returns:
507 * ASN1_SUCCESS: DER encoding OK.
509 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY.
511 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
512 * the structure NAME. *ELEMENT deleted.
515 asn1_retCode
516 asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
517 char *errorDescription)
519 node_asn *node,*p,*p2,*p3;
520 char temp[128];
521 int counter,len2,len3,len4,move,ris,tlen;
522 unsigned char class,*temp2;
523 unsigned int tag;
524 int indefinite, result;
525 const unsigned char* der = ider;
527 node=*element;
529 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
531 if(node->type&CONST_OPTION){
532 asn1_delete_structure(element);
533 return ASN1_GENERIC_ERROR;
536 counter=0;
537 move=DOWN;
538 p=node;
539 while(1){
540 ris=ASN1_SUCCESS;
541 if(move!=UP){
542 if(p->type&CONST_SET){
543 p2=_asn1_find_up(p);
544 len2=strtol(p2->value,NULL,10);
545 if(len2==-1){
546 if(!der[counter] && !der[counter+1]){
547 p=p2;
548 move=UP;
549 counter+=2;
550 continue;
553 else if(counter==len2){
554 p=p2;
555 move=UP;
556 continue;
558 else if(counter>len2){
559 asn1_delete_structure(element);
560 return ASN1_DER_ERROR;
562 p2=p2->down;
563 while(p2){
564 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
565 if(type_field(p2->type)!=TYPE_CHOICE)
566 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
567 else{
568 p3=p2->down;
569 while(p3){
570 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
571 if(ris==ASN1_SUCCESS) break;
572 p3=p3->right;
575 if(ris==ASN1_SUCCESS){
576 p2->type&=~CONST_NOT_USED;
577 p=p2;
578 break;
581 p2=p2->right;
583 if(p2==NULL){
584 asn1_delete_structure(element);
585 return ASN1_DER_ERROR;
589 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
590 p2=_asn1_find_up(p);
591 len2=strtol(p2->value,NULL,10);
592 if(counter==len2){
593 if(p->right){
594 p2=p->right;
595 move=RIGHT;
597 else move=UP;
599 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
601 p=p2;
602 continue;
606 if(type_field(p->type)==TYPE_CHOICE){
607 while(p->down){
608 if(counter<len)
609 ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
610 else
611 ris=ASN1_DER_ERROR;
612 if(ris==ASN1_SUCCESS){
613 while(p->down->right){
614 p2=p->down->right;
615 asn1_delete_structure(&p2);
617 break;
619 else if(ris==ASN1_ERROR_TYPE_ANY){
620 asn1_delete_structure(element);
621 return ASN1_ERROR_TYPE_ANY;
623 else{
624 p2=p->down;
625 asn1_delete_structure(&p2);
629 if(p->down==NULL){
630 if(!(p->type&CONST_OPTION)){
631 asn1_delete_structure(element);
632 return ASN1_DER_ERROR;
635 else
636 p=p->down;
639 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
640 p2=_asn1_find_up(p);
641 len2=strtol(p2->value,NULL,10);
642 if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
645 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
646 if(ris!=ASN1_SUCCESS){
647 if(p->type&CONST_OPTION){
648 p->type|=CONST_NOT_USED;
649 move=RIGHT;
651 else if(p->type&CONST_DEFAULT) {
652 _asn1_set_value(p,NULL,0);
653 move=RIGHT;
655 else {
656 if (errorDescription!=NULL)
657 _asn1_error_description_tag_error(p,errorDescription);
659 asn1_delete_structure(element);
660 return ASN1_TAG_ERROR;
663 else counter+=len2;
666 if(ris==ASN1_SUCCESS){
667 switch(type_field(p->type)){
668 case TYPE_NULL:
669 if(der[counter]){
670 asn1_delete_structure(element);
671 return ASN1_DER_ERROR;
673 counter++;
674 move=RIGHT;
675 break;
676 case TYPE_BOOLEAN:
677 if(der[counter++]!=1){
678 asn1_delete_structure(element);
679 return ASN1_DER_ERROR;
681 if(der[counter++]==0) _asn1_set_value(p,"F",1);
682 else _asn1_set_value(p,"T",1);
683 move=RIGHT;
684 break;
685 case TYPE_INTEGER: case TYPE_ENUMERATED:
686 len2=_asn1_get_length_der(der+counter,&len3);
687 _asn1_set_value(p,der+counter,len3+len2);
688 counter+=len3+len2;
689 move=RIGHT;
690 break;
691 case TYPE_OBJECT_ID:
692 _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
693 tlen = strlen(temp);
694 if( tlen > 0)
695 _asn1_set_value(p,temp,tlen+1);
696 counter+=len2;
697 move=RIGHT;
698 break;
699 case TYPE_TIME:
700 result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1);
701 if (result != ASN1_SUCCESS) {
702 asn1_delete_structure(element);
703 return result;
705 tlen = strlen(temp);
706 if (tlen > 0)
707 _asn1_set_value(p,temp,tlen+1);
708 counter+=len2;
709 move=RIGHT;
710 break;
711 case TYPE_OCTET_STRING:
712 len3=len-counter;
713 ris=_asn1_get_octet_string(der+counter,p,&len3);
714 if(ris != ASN1_SUCCESS) return ris;
715 counter+=len3;
716 move=RIGHT;
717 break;
718 case TYPE_GENERALSTRING:
719 len2=_asn1_get_length_der(der+counter,&len3);
720 _asn1_set_value(p,der+counter,len3+len2);
721 counter+=len3+len2;
722 move=RIGHT;
723 break;
724 case TYPE_BIT_STRING:
725 len2=_asn1_get_length_der(der+counter,&len3);
726 _asn1_set_value(p,der+counter,len3+len2);
727 counter+=len3+len2;
728 move=RIGHT;
729 break;
730 case TYPE_SEQUENCE: case TYPE_SET:
731 if(move==UP){
732 len2=strtol(p->value,NULL,10);
733 _asn1_set_value(p,NULL,0);
734 if(len2==-1){ /* indefinite length method */
735 if((der[counter]) || der[counter+1]){
736 asn1_delete_structure(element);
737 return ASN1_DER_ERROR;
739 counter+=2;
741 else{ /* definite length method */
742 if(len2!=counter){
743 asn1_delete_structure(element);
744 return ASN1_DER_ERROR;
747 move=RIGHT;
749 else{ /* move==DOWN || move==RIGHT */
750 len3=_asn1_get_length_der(der+counter,&len2);
751 counter+=len2;
752 if(len3>0){
753 _asn1_ltostr(counter+len3,temp);
754 tlen = strlen(temp);
755 if (tlen > 0)
756 _asn1_set_value(p,temp,tlen+1);
757 move=DOWN;
759 else if(len3==0){
760 p2=p->down;
761 while(p2){
762 if(type_field(p2->type)!=TYPE_TAG){
763 p3=p2->right;
764 asn1_delete_structure(&p2);
765 p2=p3;
767 else
768 p2=p2->right;
770 move=RIGHT;
772 else{ /* indefinite length method */
773 _asn1_set_value(p,"-1",3);
774 move=DOWN;
777 break;
778 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
779 if(move==UP){
780 len2=strtol(p->value,NULL,10);
781 if(len2==-1){ /* indefinite length method */
782 if((counter+2)>len) return ASN1_DER_ERROR;
783 if((der[counter]) || der[counter+1]){
784 _asn1_append_sequence_set(p);
785 p=p->down;
786 while(p->right) p=p->right;
787 move=RIGHT;
788 continue;
790 _asn1_set_value(p,NULL,0);
791 counter+=2;
793 else{ /* definite length method */
794 if(len2>counter){
795 _asn1_append_sequence_set(p);
796 p=p->down;
797 while(p->right) p=p->right;
798 move=RIGHT;
799 continue;
801 _asn1_set_value(p,NULL,0);
802 if(len2!=counter){
803 asn1_delete_structure(element);
804 return ASN1_DER_ERROR;
808 else{ /* move==DOWN || move==RIGHT */
809 len3=_asn1_get_length_der(der+counter,&len2);
810 counter+=len2;
811 if(len3){
812 if(len3>0){ /* definite length method */
813 _asn1_ltostr(counter+len3,temp);
814 tlen = strlen(temp);
816 if (tlen > 0)
817 _asn1_set_value(p,temp,tlen+1);
819 else { /* indefinite length method */
820 _asn1_set_value(p,"-1",3);
822 p2=p->down;
823 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
824 if(p2->right==NULL) _asn1_append_sequence_set(p);
825 p=p2;
828 move=RIGHT;
829 break;
830 case TYPE_ANY:
831 tag=_asn1_get_tag_der(der+counter,&class,&len2);
832 len4=_asn1_get_length_der(der+counter+len2,&len3);
834 if(len4 != -1){
835 len2+=len4;
836 _asn1_length_der(len2+len3,NULL,&len4);
837 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
838 if (temp2==NULL){
839 asn1_delete_structure(element);
840 return ASN1_MEM_ALLOC_ERROR;
843 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
844 _asn1_set_value(p,temp2,len4);
845 _asn1_afree(temp2);
846 counter+=len2+len3;
848 else{ /* indefinite length */
849 /* Check indefinite lenth method in an EXPLICIT TAG */
850 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
851 indefinite=1;
852 else
853 indefinite=0;
855 len2=len-counter;
856 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
857 if(ris != ASN1_SUCCESS){
858 asn1_delete_structure(element);
859 return ris;
861 _asn1_length_der(len2,NULL,&len4);
862 temp2=(unsigned char *)_asn1_alloca(len2+len4);
863 if (temp2==NULL){
864 asn1_delete_structure(element);
865 return ASN1_MEM_ALLOC_ERROR;
868 _asn1_octet_der(der+counter,len2,temp2,&len4);
869 _asn1_set_value(p,temp2,len4);
870 _asn1_afree(temp2);
871 counter+=len2;
873 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
874 an indefinite length method. */
875 if(indefinite){
876 if(!der[counter] && !der[counter+1]){
877 counter+=2;
879 else{
880 asn1_delete_structure(element);
881 return ASN1_DER_ERROR;
885 move=RIGHT;
886 break;
887 default:
888 move=(move==UP)?RIGHT:DOWN;
889 break;
893 if(p==node && move!=DOWN) break;
895 if(move==DOWN){
896 if(p->down) p=p->down;
897 else move=RIGHT;
899 if((move==RIGHT) && !(p->type&CONST_SET)){
900 if(p->right) p=p->right;
901 else move=UP;
903 if(move==UP) p=_asn1_find_up(p);
906 _asn1_delete_not_used(*element);
908 if(counter != len){
909 asn1_delete_structure(element);
910 return ASN1_DER_ERROR;
913 return ASN1_SUCCESS;
917 #define FOUND 1
918 #define SAME_BRANCH 2
919 #define OTHER_BRANCH 3
920 #define EXIT 4
923 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
924 * @structure: pointer to an ASN1 structure
925 * @elementName: name of the element to fill
926 * @ider: vector that contains the DER encoding of the whole structure.
927 * @len: number of bytes of *der: der[0]..der[len-1]
928 * @errorDescription: null-terminated string contains details when an
929 * error occurred.
931 * Fill the element named ELEMENTNAME with values of a DER encoding
932 * string. The sructure must just be created with function
933 * 'create_stucture'. The DER vector must contain the encoding
934 * string of the whole STRUCTURE. If an error occurs during the
935 * decoding procedure, the *STRUCTURE is deleted and set equal to
936 * %ASN1_TYPE_EMPTY.
938 * Returns:
940 * ASN1_SUCCESS: DER encoding OK.
942 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or
943 * elementName == NULL.
945 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
946 * the structure STRUCTURE. *ELEMENT deleted.
949 asn1_retCode
950 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
951 const void *ider,int len,char *errorDescription)
953 node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
954 char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
955 int nameLen=MAX_NAME_SIZE*10-1,state;
956 int counter,len2,len3,len4,move,ris, tlen;
957 unsigned char class,*temp2;
958 unsigned int tag;
959 int indefinite, result;
960 const unsigned char* der = ider;
962 node=*structure;
964 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
966 if(elementName == NULL){
967 asn1_delete_structure(structure);
968 return ASN1_ELEMENT_NOT_FOUND;
971 if(node->type&CONST_OPTION){
972 asn1_delete_structure(structure);
973 return ASN1_GENERIC_ERROR;
976 if((*structure)->name){ /* Has *structure got a name? */
977 nameLen-=strlen((*structure)->name);
978 if(nameLen>0) strcpy(currentName,(*structure)->name);
979 else{
980 asn1_delete_structure(structure);
981 return ASN1_MEM_ERROR;
983 if(!(strcmp(currentName,elementName))){
984 state=FOUND;
985 nodeFound=*structure;
987 else if(!memcmp(currentName,elementName,strlen(currentName)))
988 state=SAME_BRANCH;
989 else
990 state=OTHER_BRANCH;
992 else{ /* *structure doesn't have a name? */
993 currentName[0]=0;
994 if(elementName[0]==0){
995 state=FOUND;
996 nodeFound=*structure;
998 else{
999 state=SAME_BRANCH;
1003 counter=0;
1004 move=DOWN;
1005 p=node;
1006 while(1){
1008 ris=ASN1_SUCCESS;
1010 if(move!=UP){
1011 if(p->type&CONST_SET){
1012 p2=_asn1_find_up(p);
1013 len2=strtol(p2->value,NULL,10);
1014 if(counter==len2){
1015 p=p2;
1016 move=UP;
1017 continue;
1019 else if(counter>len2){
1020 asn1_delete_structure(structure);
1021 return ASN1_DER_ERROR;
1023 p2=p2->down;
1024 while(p2){
1025 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
1026 if(type_field(p2->type)!=TYPE_CHOICE)
1027 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1028 else{
1029 p3=p2->down;
1030 while(p3){
1031 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1032 if(ris==ASN1_SUCCESS) break;
1033 p3=p3->right;
1036 if(ris==ASN1_SUCCESS){
1037 p2->type&=~CONST_NOT_USED;
1038 p=p2;
1039 break;
1042 p2=p2->right;
1044 if(p2==NULL){
1045 asn1_delete_structure(structure);
1046 return ASN1_DER_ERROR;
1050 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1051 p2=_asn1_find_up(p);
1052 len2=strtol(p2->value,NULL,10);
1053 if(counter==len2){
1054 if(p->right){
1055 p2=p->right;
1056 move=RIGHT;
1058 else move=UP;
1060 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
1062 p=p2;
1063 continue;
1067 if(type_field(p->type)==TYPE_CHOICE){
1068 while(p->down){
1069 if(counter<len)
1070 ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
1071 else
1072 ris=ASN1_DER_ERROR;
1073 if(ris==ASN1_SUCCESS){
1074 while(p->down->right){
1075 p2=p->down->right;
1076 asn1_delete_structure(&p2);
1078 break;
1080 else if(ris==ASN1_ERROR_TYPE_ANY){
1081 asn1_delete_structure(structure);
1082 return ASN1_ERROR_TYPE_ANY;
1084 else{
1085 p2=p->down;
1086 asn1_delete_structure(&p2);
1090 if(p->down==NULL){
1091 if(!(p->type&CONST_OPTION)){
1092 asn1_delete_structure(structure);
1093 return ASN1_DER_ERROR;
1096 else
1097 p=p->down;
1100 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1101 p2=_asn1_find_up(p);
1102 len2=strtol(p2->value,NULL,10);
1103 if(counter>len2) ris=ASN1_TAG_ERROR;
1106 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1107 if(ris!=ASN1_SUCCESS){
1108 if(p->type&CONST_OPTION){
1109 p->type|=CONST_NOT_USED;
1110 move=RIGHT;
1112 else if(p->type&CONST_DEFAULT) {
1113 _asn1_set_value(p,NULL,0);
1114 move=RIGHT;
1116 else {
1117 if (errorDescription!=NULL)
1118 _asn1_error_description_tag_error(p,errorDescription);
1120 asn1_delete_structure(structure);
1121 return ASN1_TAG_ERROR;
1124 else counter+=len2;
1127 if(ris==ASN1_SUCCESS){
1128 switch(type_field(p->type)){
1129 case TYPE_NULL:
1130 if(der[counter]){
1131 asn1_delete_structure(structure);
1132 return ASN1_DER_ERROR;
1135 if(p==nodeFound) state=EXIT;
1137 counter++;
1138 move=RIGHT;
1139 break;
1140 case TYPE_BOOLEAN:
1141 if(der[counter++]!=1){
1142 asn1_delete_structure(structure);
1143 return ASN1_DER_ERROR;
1146 if(state==FOUND){
1147 if(der[counter++]==0) _asn1_set_value(p,"F",1);
1148 else _asn1_set_value(p,"T",1);
1150 if(p==nodeFound) state=EXIT;
1153 else
1154 counter++;
1156 move=RIGHT;
1157 break;
1158 case TYPE_INTEGER: case TYPE_ENUMERATED:
1159 len2=_asn1_get_length_der(der+counter,&len3);
1160 if(state==FOUND){
1161 _asn1_set_value(p,der+counter,len3+len2);
1163 if(p==nodeFound) state=EXIT;
1165 counter+=len3+len2;
1166 move=RIGHT;
1167 break;
1168 case TYPE_OBJECT_ID:
1169 if(state==FOUND){
1170 _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
1171 tlen = strlen(temp);
1173 if (tlen > 0)
1174 _asn1_set_value(p,temp,tlen+1);
1176 if(p==nodeFound) state=EXIT;
1178 else{
1179 len2=_asn1_get_length_der(der+counter,&len3);
1180 len2+=len3;
1183 counter+=len2;
1184 move=RIGHT;
1185 break;
1186 case TYPE_TIME:
1187 if(state==FOUND){
1188 result = _asn1_get_time_der(der+counter,&len2,temp,sizeof(temp)-1);
1189 if (result != ASN1_SUCCESS) {
1190 asn1_delete_structure(structure);
1191 return result;
1194 tlen = strlen(temp);
1195 if (tlen > 0)
1196 _asn1_set_value(p,temp,tlen+1);
1198 if(p==nodeFound) state=EXIT;
1200 else{
1201 len2=_asn1_get_length_der(der+counter,&len3);
1202 len2+=len3;
1205 counter+=len2;
1206 move=RIGHT;
1207 break;
1208 case TYPE_OCTET_STRING:
1209 len3=len-counter;
1210 if(state==FOUND){
1211 ris=_asn1_get_octet_string(der+counter,p,&len3);
1212 if(p==nodeFound) state=EXIT;
1214 else
1215 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1217 if(ris != ASN1_SUCCESS) return ris;
1218 counter+=len3;
1219 move=RIGHT;
1220 break;
1221 case TYPE_GENERALSTRING:
1222 len2=_asn1_get_length_der(der+counter,&len3);
1223 if(state==FOUND){
1224 _asn1_set_value(p,der+counter,len3+len2);
1226 if(p==nodeFound) state=EXIT;
1228 counter+=len3+len2;
1229 move=RIGHT;
1230 break;
1231 case TYPE_BIT_STRING:
1232 len2=_asn1_get_length_der(der+counter,&len3);
1233 if(state==FOUND){
1234 _asn1_set_value(p,der+counter,len3+len2);
1236 if(p==nodeFound) state=EXIT;
1238 counter+=len3+len2;
1239 move=RIGHT;
1240 break;
1241 case TYPE_SEQUENCE: case TYPE_SET:
1242 if(move==UP){
1243 len2=strtol(p->value,NULL,10);
1244 _asn1_set_value(p,NULL,0);
1245 if(len2==-1){ /* indefinite length method */
1246 if((der[counter]) || der[counter+1]){
1247 asn1_delete_structure(structure);
1248 return ASN1_DER_ERROR;
1250 counter+=2;
1252 else{ /* definite length method */
1253 if(len2!=counter){
1254 asn1_delete_structure(structure);
1255 return ASN1_DER_ERROR;
1258 if(p==nodeFound) state=EXIT;
1259 move=RIGHT;
1261 else{ /* move==DOWN || move==RIGHT */
1262 if(state==OTHER_BRANCH){
1263 len3=_asn1_get_length_der(der+counter,&len2);
1264 counter+=len2+len3;
1265 move=RIGHT;
1267 else { /* state==SAME_BRANCH or state==FOUND */
1268 len3=_asn1_get_length_der(der+counter,&len2);
1269 counter+=len2;
1270 if(len3>0){
1271 _asn1_ltostr(counter+len3,temp);
1272 tlen = strlen(temp);
1274 if(tlen > 0)
1275 _asn1_set_value(p,temp,tlen+1);
1276 move=DOWN;
1278 else if(len3==0){
1279 p2=p->down;
1280 while(p2){
1281 if(type_field(p2->type)!=TYPE_TAG){
1282 p3=p2->right;
1283 asn1_delete_structure(&p2);
1284 p2=p3;
1286 else
1287 p2=p2->right;
1289 move=RIGHT;
1291 else{ /* indefinite length method */
1292 _asn1_set_value(p,"-1",3);
1293 move=DOWN;
1297 break;
1298 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1299 if(move==UP){
1300 len2=strtol(p->value,NULL,10);
1301 if(len2>counter){
1302 _asn1_append_sequence_set(p);
1303 p=p->down;
1304 while(p->right) p=p->right;
1305 move=RIGHT;
1306 continue;
1308 _asn1_set_value(p,NULL,0);
1309 if(len2!=counter){
1310 asn1_delete_structure(structure);
1311 return ASN1_DER_ERROR;
1314 if(p==nodeFound) state=EXIT;
1316 else{ /* move==DOWN || move==RIGHT */
1317 if(state==OTHER_BRANCH){
1318 len3=_asn1_get_length_der(der+counter,&len2);
1319 counter+=len2+len3;
1320 move=RIGHT;
1322 else{ /* state==FOUND or state==SAME_BRANCH */
1323 len3=_asn1_get_length_der(der+counter,&len2);
1324 counter+=len2;
1325 if(len3){
1326 _asn1_ltostr(counter+len3,temp);
1327 tlen = strlen(temp);
1329 if (tlen > 0)
1330 _asn1_set_value(p,temp,tlen+1);
1331 p2=p->down;
1332 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1333 if(p2->right==NULL) _asn1_append_sequence_set(p);
1334 p=p2;
1335 state=FOUND;
1340 break;
1341 case TYPE_ANY:
1342 tag=_asn1_get_tag_der(der+counter,&class,&len2);
1343 len4=_asn1_get_length_der(der+counter+len2,&len3);
1345 if(len4 != -1){
1346 len2+=len4;
1347 if(state==FOUND){
1348 _asn1_length_der(len2+len3,NULL,&len4);
1349 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
1350 if (temp2==NULL){
1351 asn1_delete_structure(structure);
1352 return ASN1_MEM_ALLOC_ERROR;
1355 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
1356 _asn1_set_value(p,temp2,len4);
1357 _asn1_afree(temp2);
1359 if(p==nodeFound) state=EXIT;
1361 counter+=len2+len3;
1363 else{ /* indefinite length */
1364 /* Check indefinite lenth method in an EXPLICIT TAG */
1365 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1366 indefinite=1;
1367 else
1368 indefinite=0;
1370 len2=len-counter;
1371 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1372 if(ris != ASN1_SUCCESS){
1373 asn1_delete_structure(structure);
1374 return ris;
1377 if(state==FOUND){
1378 _asn1_length_der(len2,NULL,&len4);
1379 temp2=(unsigned char *)_asn1_alloca(len2+len4);
1380 if (temp2==NULL){
1381 asn1_delete_structure(structure);
1382 return ASN1_MEM_ALLOC_ERROR;
1385 _asn1_octet_der(der+counter,len2,temp2,&len4);
1386 _asn1_set_value(p,temp2,len4);
1387 _asn1_afree(temp2);
1389 if(p==nodeFound) state=EXIT;
1392 counter+=len2;
1394 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1395 an indefinite length method. */
1396 if(indefinite){
1397 if(!der[counter] && !der[counter+1]){
1398 counter+=2;
1400 else{
1401 asn1_delete_structure(structure);
1402 return ASN1_DER_ERROR;
1406 move=RIGHT;
1407 break;
1409 default:
1410 move=(move==UP)?RIGHT:DOWN;
1411 break;
1415 if((p==node && move!=DOWN) || (state==EXIT)) break;
1417 if(move==DOWN){
1418 if(p->down){
1419 p=p->down;
1421 if(state != FOUND){
1422 nameLen-=strlen(p->name)+1;
1423 if(nameLen>0){
1424 if(currentName[0]) strcat(currentName,".");
1425 strcat(currentName,p->name);
1427 else{
1428 asn1_delete_structure(structure);
1429 return ASN1_MEM_ERROR;
1431 if(!(strcmp(currentName,elementName))){
1432 state=FOUND;
1433 nodeFound=p;
1435 else if(!memcmp(currentName,elementName,strlen(currentName)))
1436 state=SAME_BRANCH;
1437 else
1438 state=OTHER_BRANCH;
1441 else move=RIGHT;
1444 if((move==RIGHT) && !(p->type&CONST_SET)){
1445 if(p->right){
1446 p=p->right;
1448 if(state != FOUND){
1449 dot_p=char_p=currentName;
1450 while((char_p=strchr(char_p,'.'))){
1451 dot_p=char_p++;
1452 dot_p++;
1455 nameLen+=strlen(currentName)-(dot_p-currentName);
1456 *dot_p=0;
1458 nameLen-=strlen(p->name);
1459 if(nameLen>0) strcat(currentName,p->name);
1460 else{
1461 asn1_delete_structure(structure);
1462 return ASN1_MEM_ERROR;
1465 if(!(strcmp(currentName,elementName))){
1466 state=FOUND;
1467 nodeFound=p;
1469 else if(!memcmp(currentName,elementName,strlen(currentName)))
1470 state=SAME_BRANCH;
1471 else
1472 state=OTHER_BRANCH;
1475 else move=UP;
1478 if(move==UP){
1479 p=_asn1_find_up(p);
1481 if(state != FOUND){
1482 dot_p=char_p=currentName;
1483 while((char_p=strchr(char_p,'.'))){
1484 dot_p=char_p++;
1485 dot_p++;
1488 nameLen+=strlen(currentName)-(dot_p-currentName);
1489 *dot_p=0;
1491 if(!(strcmp(currentName,elementName))){
1492 state=FOUND;
1493 nodeFound=p;
1495 else if(!memcmp(currentName,elementName,strlen(currentName)))
1496 state=SAME_BRANCH;
1497 else
1498 state=OTHER_BRANCH;
1503 _asn1_delete_not_used(*structure);
1505 if(counter > len){
1506 asn1_delete_structure(structure);
1507 return ASN1_DER_ERROR;
1510 return ASN1_SUCCESS;
1516 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1517 * @element: pointer to an ASN1 element
1518 * @ider: vector that contains the DER encoding.
1519 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
1520 * @name_element: an element of NAME structure.
1521 * @start: the position of the first byte of NAME_ELEMENT decoding
1522 * (@ider[*start])
1523 * @end: the position of the last byte of NAME_ELEMENT decoding
1524 * (@ider[*end])
1526 * Find the start and end point of an element in a DER encoding
1527 * string. I mean that if you have a der encoding and you have
1528 * already used the function "asn1_der_decoding" to fill a structure,
1529 * it may happen that you want to find the piece of string concerning
1530 * an element of the structure.
1532 * Example: the sequence "tbsCertificate" inside an X509 certificate.
1534 * Returns:
1536 * ASN1_SUCCESS: DER encoding OK.
1538 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or
1539 * NAME_ELEMENT is not a valid element.
1541 * ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match
1542 * the structure ELEMENT.
1545 asn1_retCode
1546 asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
1547 const char *name_element,int *start, int *end)
1549 node_asn *node,*node_to_find,*p,*p2,*p3;
1550 int counter,len2,len3,len4,move,ris;
1551 unsigned char class;
1552 unsigned int tag;
1553 int indefinite;
1554 const unsigned char* der = ider;
1556 node=element;
1558 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1560 node_to_find=_asn1_find_node(node,name_element);
1562 if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
1564 if(node_to_find==node){
1565 *start=0;
1566 *end=len-1;
1567 return ASN1_SUCCESS;
1570 if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
1572 counter=0;
1573 move=DOWN;
1574 p=node;
1575 while(1){
1576 ris=ASN1_SUCCESS;
1578 if(move!=UP){
1579 if(p->type&CONST_SET){
1580 p2=_asn1_find_up(p);
1581 len2=strtol(p2->value,NULL,10);
1582 if(len2==-1){
1583 if(!der[counter] && !der[counter+1]){
1584 p=p2;
1585 move=UP;
1586 counter+=2;
1587 continue;
1590 else if(counter==len2){
1591 p=p2;
1592 move=UP;
1593 continue;
1595 else if(counter>len2) return ASN1_DER_ERROR;
1596 p2=p2->down;
1597 while(p2){
1598 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
1599 if(type_field(p2->type)!=TYPE_CHOICE)
1600 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1601 else{
1602 p3=p2->down;
1603 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1605 if(ris==ASN1_SUCCESS){
1606 p2->type&=~CONST_NOT_USED;
1607 p=p2;
1608 break;
1611 p2=p2->right;
1613 if(p2==NULL) return ASN1_DER_ERROR;
1616 if(p==node_to_find) *start=counter;
1618 if(type_field(p->type)==TYPE_CHOICE){
1619 p=p->down;
1620 ris=_asn1_extract_tag_der(p,der+counter,&len2);
1621 if(p==node_to_find) *start=counter;
1624 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1625 if(ris!=ASN1_SUCCESS){
1626 if(p->type&CONST_OPTION){
1627 p->type|=CONST_NOT_USED;
1628 move=RIGHT;
1630 else if(p->type&CONST_DEFAULT) {
1631 move=RIGHT;
1633 else {
1634 return ASN1_TAG_ERROR;
1637 else counter+=len2;
1640 if(ris==ASN1_SUCCESS){
1641 switch(type_field(p->type)){
1642 case TYPE_NULL:
1643 if(der[counter]) return ASN1_DER_ERROR;
1644 counter++;
1645 move=RIGHT;
1646 break;
1647 case TYPE_BOOLEAN:
1648 if(der[counter++]!=1) return ASN1_DER_ERROR;
1649 counter++;
1650 move=RIGHT;
1651 break;
1652 case TYPE_INTEGER: case TYPE_ENUMERATED:
1653 len2=_asn1_get_length_der(der+counter,&len3);
1654 counter+=len3+len2;
1655 move=RIGHT;
1656 break;
1657 case TYPE_OBJECT_ID:
1658 len2=_asn1_get_length_der(der+counter,&len3);
1659 counter+=len2+len3;
1660 move=RIGHT;
1661 break;
1662 case TYPE_TIME:
1663 len2=_asn1_get_length_der(der+counter,&len3);
1664 counter+=len2+len3;
1665 move=RIGHT;
1666 break;
1667 case TYPE_OCTET_STRING:
1668 len3=len-counter;
1669 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1670 if(ris != ASN1_SUCCESS) return ris;
1671 counter+=len3;
1672 move=RIGHT;
1673 break;
1674 case TYPE_GENERALSTRING:
1675 len2=_asn1_get_length_der(der+counter,&len3);
1676 counter+=len3+len2;
1677 move=RIGHT;
1678 break;
1679 case TYPE_BIT_STRING:
1680 len2=_asn1_get_length_der(der+counter,&len3);
1681 counter+=len3+len2;
1682 move=RIGHT;
1683 break;
1684 case TYPE_SEQUENCE: case TYPE_SET:
1685 if(move!=UP){
1686 len3=_asn1_get_length_der(der+counter,&len2);
1687 counter+=len2;
1688 if(len3==0) move=RIGHT;
1689 else move=DOWN;
1691 else{
1692 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1693 counter+=2;
1694 move=RIGHT;
1696 break;
1697 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1698 if(move!=UP){
1699 len3=_asn1_get_length_der(der+counter,&len2);
1700 counter+=len2;
1701 if((len3==-1) && !der[counter] && !der[counter+1])
1702 counter+=2;
1703 else if(len3){
1704 p2=p->down;
1705 while((type_field(p2->type)==TYPE_TAG) ||
1706 (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1707 p=p2;
1710 else{
1711 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1712 counter+=2;
1714 move=RIGHT;
1715 break;
1716 case TYPE_ANY:
1717 tag=_asn1_get_tag_der(der+counter,&class,&len2);
1718 len4=_asn1_get_length_der(der+counter+len2,&len3);
1720 if(len4 != -1){
1721 counter+=len2+len4+len3;
1723 else{ /* indefinite length */
1724 /* Check indefinite lenth method in an EXPLICIT TAG */
1725 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1726 indefinite=1;
1727 else
1728 indefinite=0;
1730 len2=len-counter;
1731 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1732 if(ris != ASN1_SUCCESS)
1733 return ris;
1734 counter+=len2;
1736 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1737 an indefinite length method. */
1738 if(indefinite){
1739 if(!der[counter] && !der[counter+1])
1740 counter+=2;
1741 else
1742 return ASN1_DER_ERROR;
1745 move=RIGHT;
1746 break;
1747 default:
1748 move=(move==UP)?RIGHT:DOWN;
1749 break;
1753 if((p==node_to_find) && (move==RIGHT)){
1754 *end=counter-1;
1755 return ASN1_SUCCESS;
1758 if(p==node && move!=DOWN) break;
1760 if(move==DOWN){
1761 if(p->down) p=p->down;
1762 else move=RIGHT;
1764 if((move==RIGHT) && !(p->type&CONST_SET)){
1765 if(p->right) p=p->right;
1766 else move=UP;
1768 if(move==UP) p=_asn1_find_up(p);
1771 return ASN1_ELEMENT_NOT_FOUND;
1776 * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure.
1777 * @definitions: ASN1 definitions
1778 * @element: pointer to an ASN1 structure
1780 * Expands every "ANY DEFINED BY" element of a structure created from
1781 * a DER decoding process (asn1_der_decoding function). The element ANY
1782 * must be defined by an OBJECT IDENTIFIER. The type used to expand
1783 * the element ANY is the first one following the definition of
1784 * the actual value of the OBJECT IDENTIFIER.
1787 * Returns:
1789 * ASN1_SUCCESS: Substitution OK.
1791 * ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be
1792 * expanded due to a problem in OBJECT_ID -> TYPE association.
1794 * other errors: Result of der decoding process.
1797 asn1_retCode
1798 asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
1800 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1801 asn1_retCode retCode=ASN1_SUCCESS,result;
1802 int len,len2,len3;
1803 ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
1804 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1806 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1807 return ASN1_ELEMENT_NOT_FOUND;
1809 strcpy(definitionsName,definitions->name);
1810 strcat(definitionsName,".");
1812 p=*element;
1813 while(p){
1815 switch(type_field(p->type)){
1816 case TYPE_ANY:
1817 if((p->type&CONST_DEFINED_BY) && (p->value)){
1818 /* search the "DEF_BY" element */
1819 p2=p->down;
1820 while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
1821 p2=p2->right;
1823 if(!p2){
1824 retCode=ASN1_ERROR_TYPE_ANY;
1825 break;
1828 p3=_asn1_find_up(p);
1830 if(!p3){
1831 retCode=ASN1_ERROR_TYPE_ANY;
1832 break;
1835 p3=p3->down;
1836 while(p3){
1837 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1838 p3=p3->right;
1841 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1842 (p3->value==NULL)){
1844 p3=_asn1_find_up(p);
1845 p3=_asn1_find_up(p3);
1847 if(!p3){
1848 retCode=ASN1_ERROR_TYPE_ANY;
1849 break;
1852 p3=p3->down;
1854 while(p3){
1855 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1856 p3=p3->right;
1859 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1860 (p3->value==NULL)){
1861 retCode=ASN1_ERROR_TYPE_ANY;
1862 break;
1866 /* search the OBJECT_ID into definitions */
1867 p2=definitions->down;
1868 while(p2){
1869 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
1870 (p2->type & CONST_ASSIGN)){
1871 strcpy(name,definitionsName);
1872 strcat(name,p2->name);
1874 len=MAX_NAME_SIZE;
1875 result=asn1_read_value(definitions,name,value,&len);
1877 if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
1878 p2=p2->right; /* pointer to the structure to
1879 use for expansion */
1880 while((p2) && (p2->type & CONST_ASSIGN))
1881 p2=p2->right;
1883 if(p2){
1884 strcpy(name,definitionsName);
1885 strcat(name,p2->name);
1887 result=asn1_create_element(definitions,name,&aux);
1888 if(result == ASN1_SUCCESS){
1889 _asn1_set_name(aux,p->name);
1890 len2=_asn1_get_length_der(p->value,&len3);
1892 result=asn1_der_decoding(&aux,p->value+len3,len2,
1893 errorDescription);
1894 if(result == ASN1_SUCCESS){
1896 _asn1_set_right(aux,p->right);
1897 _asn1_set_right(p,aux);
1899 result=asn1_delete_structure(&p);
1900 if(result == ASN1_SUCCESS){
1901 p=aux;
1902 aux=ASN1_TYPE_EMPTY;
1903 break;
1905 else{ /* error with asn1_delete_structure */
1906 asn1_delete_structure(&aux);
1907 retCode=result;
1908 break;
1911 else{/* error with asn1_der_decoding */
1912 retCode=result;
1913 break;
1916 else{/* error with asn1_create_element */
1917 retCode=result;
1918 break;
1921 else{/* error with the pointer to the structure to exapand */
1922 retCode=ASN1_ERROR_TYPE_ANY;
1923 break;
1927 p2=p2->right;
1928 } /* end while */
1930 if(!p2){
1931 retCode=ASN1_ERROR_TYPE_ANY;
1932 break;
1936 break;
1937 default:
1938 break;
1942 if(p->down){
1943 p=p->down;
1945 else if(p==*element){
1946 p=NULL;
1947 break;
1949 else if(p->right) p=p->right;
1950 else{
1951 while(1){
1952 p=_asn1_find_up(p);
1953 if(p==*element){
1954 p=NULL;
1955 break;
1957 if(p->right){
1958 p=p->right;
1959 break;
1965 return retCode;
1971 * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure.
1972 * @definitions: ASN1 definitions
1973 * @element: pointer to an ASN1 structure
1974 * @octetName: name of the OCTECT STRING field to expand.
1975 * @objectName: name of the OBJECT IDENTIFIER field to use to define
1976 * the type for expansion.
1978 * Expands an "OCTET STRING" element of a structure created from a
1979 * DER decoding process (asn1_der_decoding function). The type used
1980 * for expansion is the first one following the definition of the
1981 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
1983 * Returns:
1985 * ASN1_SUCCESS: Substitution OK.
1987 * ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct.
1989 * ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use
1990 * for expansion.
1992 * other errors: result of der decoding process.
1994 asn1_retCode
1995 asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
1996 const char *octetName,const char *objectName)
1998 char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1999 asn1_retCode retCode=ASN1_SUCCESS,result;
2000 int len,len2,len3;
2001 ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
2002 ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
2003 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
2005 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
2006 return ASN1_ELEMENT_NOT_FOUND;
2008 octetNode=_asn1_find_node(*element,octetName);
2009 if(octetNode==ASN1_TYPE_EMPTY)
2010 return ASN1_ELEMENT_NOT_FOUND;
2011 if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
2012 return ASN1_ELEMENT_NOT_FOUND;
2013 if(octetNode->value==NULL)
2014 return ASN1_VALUE_NOT_FOUND;
2016 objectNode=_asn1_find_node(*element,objectName);
2017 if(objectNode==ASN1_TYPE_EMPTY)
2018 return ASN1_ELEMENT_NOT_FOUND;
2020 if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
2021 return ASN1_ELEMENT_NOT_FOUND;
2023 if(objectNode->value==NULL)
2024 return ASN1_VALUE_NOT_FOUND;
2027 /* search the OBJECT_ID into definitions */
2028 p2=definitions->down;
2029 while(p2){
2030 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
2031 (p2->type & CONST_ASSIGN)){
2032 strcpy(name,definitions->name);
2033 strcat(name,".");
2034 strcat(name,p2->name);
2036 len = sizeof(value);
2037 result=asn1_read_value(definitions,name,value,&len);
2039 if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
2041 p2=p2->right; /* pointer to the structure to
2042 use for expansion */
2043 while((p2) && (p2->type & CONST_ASSIGN))
2044 p2=p2->right;
2046 if(p2){
2047 strcpy(name,definitions->name);
2048 strcat(name,".");
2049 strcat(name,p2->name);
2051 result=asn1_create_element(definitions,name,&aux);
2052 if(result == ASN1_SUCCESS){
2053 _asn1_set_name(aux,octetNode->name);
2054 len2=_asn1_get_length_der(octetNode->value,&len3);
2056 result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
2057 errorDescription);
2058 if(result == ASN1_SUCCESS){
2060 _asn1_set_right(aux,octetNode->right);
2061 _asn1_set_right(octetNode,aux);
2063 result=asn1_delete_structure(&octetNode);
2064 if(result == ASN1_SUCCESS){
2065 aux=ASN1_TYPE_EMPTY;
2066 break;
2068 else{ /* error with asn1_delete_structure */
2069 asn1_delete_structure(&aux);
2070 retCode=result;
2071 break;
2074 else{/* error with asn1_der_decoding */
2075 retCode=result;
2076 break;
2079 else{/* error with asn1_create_element */
2080 retCode=result;
2081 break;
2084 else{/* error with the pointer to the structure to exapand */
2085 retCode=ASN1_VALUE_NOT_VALID;
2086 break;
2091 p2=p2->right;
2095 if(!p2) retCode=ASN1_VALUE_NOT_VALID;
2097 return retCode;