Fix typo.
[shishi.git] / asn1 / decoding.c
blob3e3e9d85f2dbb99467f959450a613876d2f4d10b
1 /*
2 * Copyright (C) 2002 Fabio Fiorina
4 * This file is part of LIBASN1.
6 * The LIBTASN1 library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /*****************************************************/
23 /* File: decoding.c */
24 /* Description: Functions to manage DER decoding */
25 /*****************************************************/
27 #include <int.h>
28 #include <errors.h>
29 #include "der.h"
30 #include "parser_aux.h"
31 #include <gstr.h>
32 #include "structure.h"
33 #include "element.h"
36 void
37 _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
40 Estrcpy(ErrorDescription,":: tag error near element '");
41 _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
42 MAX_ERROR_DESCRIPTION_SIZE-40);
43 Estrcat(ErrorDescription,"'");
48 signed long
49 _asn1_get_length_der(const unsigned char *der,int *len)
51 unsigned long ans;
52 int k,punt;
54 if(!(der[0]&128)){
55 /* short form */
56 *len=1;
57 return der[0];
59 else{
60 /* Long form */
61 k=der[0]&0x7F;
62 punt=1;
63 if(k){ /* definite length method */
64 ans=0;
65 while(punt<=k) ans=ans*256+der[punt++];
67 else{ /* indefinite lenght method */
68 ans=-1;
71 *len=punt;
72 return ans;
79 unsigned int
80 _asn1_get_tag_der(const unsigned char *der,unsigned char *class,int *len)
82 int punt,ris;
84 if (der==NULL || len == NULL) return ASN1_DER_ERROR;
85 *class=der[0]&0xE0;
86 if((der[0]&0x1F)!=0x1F){
87 /* short form */
88 *len=1;
89 ris=der[0]&0x1F;
91 else{
92 /* Long form */
93 punt=1;
94 ris=0;
95 while(der[punt]&128) ris=ris*128+(der[punt++]&0x7F);
96 ris=ris*128+(der[punt++]&0x7F);
97 *len=punt;
99 return ris;
106 _asn1_get_octet_der(const unsigned char *der,int *der_len,unsigned char *str,int str_size, int *str_len)
108 int len_len;
110 /* if(str==NULL) return ASN1_SUCCESS; */
111 *str_len=_asn1_get_length_der(der,&len_len);
113 *der_len=*str_len+len_len;
114 if ( str_size >= *str_len)
115 memcpy(str,der+len_len,*str_len);
116 else {
117 return ASN1_MEM_ERROR;
120 return ASN1_SUCCESS;
126 void
127 _asn1_get_time_der(const unsigned char *der,int *der_len,unsigned char *str)
129 int len_len,str_len;
131 if(str==NULL) return;
132 str_len=_asn1_get_length_der(der,&len_len);
133 memcpy(str,der+len_len,str_len);
134 str[str_len]=0;
135 *der_len=str_len+len_len;
140 void
141 _asn1_get_objectid_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size)
143 int len_len,len,k;
144 char temp[20];
145 unsigned long val,val1;
147 if(str==NULL) return;
148 len=_asn1_get_length_der(der,&len_len);
150 val1=der[len_len]/40;
151 val=der[len_len]-val1*40;
153 _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
154 _asn1_str_cat(str, str_size, ".");
155 _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
157 val=0;
158 for(k=1;k<len;k++){
159 val=val<<7;
160 val|=der[len_len+k]&0x7F;
161 if(!(der[len_len+k]&0x80)){
162 _asn1_str_cat(str, str_size,".");
163 _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
164 val=0;
167 *der_len=len+len_len;
174 _asn1_get_bit_der(const unsigned char *der,int *der_len,unsigned char *str, int str_size, int *bit_len)
176 int len_len,len_byte;
178 len_byte=_asn1_get_length_der(der,&len_len)-1;
180 *der_len=len_byte+len_len+1;
181 *bit_len=len_byte*8-der[len_len];
183 if (str_size >= len_byte)
184 memcpy(str,der+len_len+1,len_byte);
185 else {
186 return ASN1_MEM_ERROR;
189 return ASN1_SUCCESS;
196 _asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len)
198 node_asn *p;
199 int counter,len2,len3,is_tag_implicit;
200 unsigned long tag,tag_implicit=0;
201 unsigned char class,class2,class_implicit=0;
204 counter=is_tag_implicit=0;
206 if(node->type&CONST_TAG){
207 p=node->down;
208 while(p){
209 if(type_field(p->type)==TYPE_TAG){
210 if(p->type&CONST_APPLICATION) class2=APPLICATION;
211 else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
212 else if(p->type&CONST_PRIVATE) class2=PRIVATE;
213 else class2=CONTEXT_SPECIFIC;
215 if(p->type&CONST_EXPLICIT){
216 tag=_asn1_get_tag_der(der+counter,&class,&len2);
217 counter+=len2;
218 len3=_asn1_get_length_der(der+counter,&len2);
219 counter+=len2;
220 if(!is_tag_implicit){
221 if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
222 return ASN1_TAG_ERROR;
224 else{ /* TAG_IMPLICIT */
225 if((class!=class_implicit) || (tag!=tag_implicit))
226 return ASN1_TAG_ERROR;
229 is_tag_implicit=0;
231 else{ /* TAG_IMPLICIT */
232 if(!is_tag_implicit){
233 if((type_field(node->type)==TYPE_SEQUENCE) ||
234 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
235 (type_field(node->type)==TYPE_SET) ||
236 (type_field(node->type)==TYPE_SET_OF)) class2|=STRUCTURED;
237 class_implicit=class2;
238 tag_implicit=strtoul(p->value,NULL,10);
239 is_tag_implicit=1;
243 p=p->right;
247 if(is_tag_implicit){
248 tag=_asn1_get_tag_der(der+counter,&class,&len2);
249 if((class!=class_implicit) || (tag!=tag_implicit)){
250 if(type_field(node->type)==TYPE_OCTET_STRING){
251 class_implicit |= STRUCTURED;
252 if((class!=class_implicit) || (tag!=tag_implicit))
253 return ASN1_TAG_ERROR;
255 else
256 return ASN1_TAG_ERROR;
259 else{
260 if(type_field(node->type)==TYPE_TAG){
261 counter=0;
262 *der_len=counter;
263 return ASN1_SUCCESS;
266 tag=_asn1_get_tag_der(der+counter,&class,&len2);
267 switch(type_field(node->type)){
268 case TYPE_NULL:
269 if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
270 break;
271 case TYPE_BOOLEAN:
272 if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
273 break;
274 case TYPE_INTEGER:
275 if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
276 break;
277 case TYPE_ENUMERATED:
278 if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
279 break;
280 case TYPE_OBJECT_ID:
281 if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
282 break;
283 case TYPE_TIME:
284 if(node->type&CONST_UTC){
285 if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
287 else{
288 if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime))
289 return ASN1_DER_ERROR;
291 break;
292 case TYPE_OCTET_STRING:
293 if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
294 || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
295 break;
296 case TYPE_GENERALSTRING:
297 if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
298 break;
299 case TYPE_BIT_STRING:
300 if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
301 break;
302 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
303 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE))
304 return ASN1_DER_ERROR;
305 break;
306 case TYPE_SET: case TYPE_SET_OF:
307 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET))
308 return ASN1_DER_ERROR;
309 break;
310 case TYPE_ANY:
311 counter-=len2;
312 break;
313 default:
314 return ASN1_DER_ERROR;
315 break;
319 counter+=len2;
320 *der_len=counter;
321 return ASN1_SUCCESS;
325 int
326 _asn1_delete_not_used(node_asn *node)
328 node_asn *p,*p2;
330 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
332 p=node;
333 while(p){
334 if(p->type&CONST_NOT_USED){
335 p2=NULL;
336 if(p!=node){
337 p2=_asn1_find_left(p);
338 if(!p2) p2=_asn1_find_up(p);
340 asn1_delete_structure(&p);
341 p=p2;
344 if(!p) break; /* reach node */
346 if(p->down){
347 p=p->down;
349 else{
350 if(p==node) p=NULL;
351 else if(p->right) p=p->right;
352 else{
353 while(1){
354 p=_asn1_find_up(p);
355 if(p==node){
356 p=NULL;
357 break;
359 if(p->right){
360 p=p->right;
361 break;
367 return ASN1_SUCCESS;
371 asn1_retCode
372 _asn1_get_octet_string(const unsigned char* der,node_asn *node,int* len)
374 int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
375 char *temp,*temp2;
377 counter=0;
379 if(*(der-1) & STRUCTURED){
380 tot_len=0;
381 indefinite=_asn1_get_length_der(der,&len3);
383 counter+=len3;
384 if(indefinite>=0) indefinite+=len3;
386 while(1){
387 if(counter>(*len)) return ASN1_DER_ERROR;
389 if(indefinite==-1){
390 if((der[counter]==0) && (der[counter+1]==0)){
391 counter+=2;
392 break;
395 else if(counter>=indefinite) break;
397 if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
399 counter++;
401 len2=_asn1_get_length_der(der+counter,&len3);
402 if(len2 <= 0) return ASN1_DER_ERROR;
404 counter+=len3+len2;
405 tot_len+=len2;
408 /* copy */
409 if(node){
410 _asn1_length_der(tot_len,NULL,&len2);
411 temp=(unsigned char *)_asn1_alloca(len2+tot_len);
412 if (temp==NULL){
413 return ASN1_MEM_ALLOC_ERROR;
416 _asn1_length_der(tot_len,temp,&len2);
417 tot_len+=len2;
418 temp2=temp+len2;
419 len2=_asn1_get_length_der(der,&len3);
420 counter2=len3+1;
422 if(indefinite==-1) counter_end=counter-2;
423 else counter_end=counter;
425 while(counter2<counter_end){
426 len2=_asn1_get_length_der(der+counter2,&len3);
427 memcpy(temp2,der+counter2+len3,len2);
428 temp2+=len2;
429 counter2+=len2+len3+1;
431 _asn1_set_value(node,temp,tot_len);
432 _asn1_afree(temp);
435 else{ /* NOT STRUCTURED */
436 len2=_asn1_get_length_der(der,&len3);
437 if(node)
438 _asn1_set_value(node,der,len3+len2);
439 counter=len3+len2;
442 *len=counter;
443 return ASN1_SUCCESS;
448 asn1_retCode
449 _asn1_get_indefinite_length_string(const unsigned char* der,int* len)
451 int len2,len3,counter,indefinite;
452 unsigned int tag;
453 unsigned char class;
455 counter=indefinite=0;
457 while(1){
458 if((*len)<counter) return ASN1_DER_ERROR;
460 if((der[counter]==0) && (der[counter+1]==0)){
461 counter+=2;
462 indefinite--;
463 if(indefinite<=0) break;
464 else continue;
467 tag=_asn1_get_tag_der(der+counter,&class,&len2);
468 counter+=len2;
469 len2=_asn1_get_length_der(der+counter,&len3);
470 if(len2 == -1){
471 indefinite++;
472 counter+=1;
474 else{
475 counter+=len2+len3;
479 *len=counter;
480 return ASN1_SUCCESS;
486 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
487 * @element: pointer to an ASN1 structure
488 * @der: vector that contains the DER encoding.
489 * @len: number of bytes of *der: der[0]..der[len-1]
490 * Description:
492 * Fill the structure *ELEMENT with values of a DER encoding string. The sructure must just be
493 * created with function 'create_stucture'.
494 * If an error accurs during de decoding procedure, the *ELEMENT is deleted
495 * and set equal to ASN1_TYPE_EMPTY.
497 * Returns:
499 * ASN1_SUCCESS\: DER encoding OK
501 * ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY.
503 * ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure NAME. *ELEMENT deleted.
506 asn1_retCode
507 asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len,
508 char *errorDescription)
510 node_asn *node,*p,*p2,*p3;
511 char temp[128];
512 int counter,len2,len3,len4,move,ris;
513 unsigned char class,*temp2;
514 unsigned int tag;
515 int indefinite;
517 node=*element;
519 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
521 if(node->type&CONST_OPTION){
522 asn1_delete_structure(element);
523 return ASN1_GENERIC_ERROR;
526 counter=0;
527 move=DOWN;
528 p=node;
529 while(1){
530 ris=ASN1_SUCCESS;
531 if(move!=UP){
532 if(p->type&CONST_SET){
533 p2=_asn1_find_up(p);
534 len2=strtol(p2->value,NULL,10);
535 if(len2==-1){
536 if(!der[counter] && !der[counter+1]){
537 p=p2;
538 move=UP;
539 counter+=2;
540 continue;
543 else if(counter==len2){
544 p=p2;
545 move=UP;
546 continue;
548 else if(counter>len2){
549 asn1_delete_structure(element);
550 return ASN1_DER_ERROR;
552 p2=p2->down;
553 while(p2){
554 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
555 if(type_field(p2->type)!=TYPE_CHOICE)
556 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
557 else{
558 p3=p2->down;
559 while(p3){
560 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
561 if(ris==ASN1_SUCCESS) break;
562 p3=p3->right;
565 if(ris==ASN1_SUCCESS){
566 p2->type&=~CONST_NOT_USED;
567 p=p2;
568 break;
571 p2=p2->right;
573 if(p2==NULL){
574 asn1_delete_structure(element);
575 return ASN1_DER_ERROR;
579 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
580 p2=_asn1_find_up(p);
581 len2=strtol(p2->value,NULL,10);
582 if(counter==len2){
583 if(p->right){
584 p2=p->right;
585 move=RIGHT;
587 else move=UP;
589 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
591 p=p2;
592 continue;
596 if(type_field(p->type)==TYPE_CHOICE){
597 while(p->down){
598 if(counter<len)
599 ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
600 else
601 ris=ASN1_DER_ERROR;
602 if(ris==ASN1_SUCCESS){
603 while(p->down->right){
604 p2=p->down->right;
605 asn1_delete_structure(&p2);
607 break;
609 else if(ris==ASN1_ERROR_TYPE_ANY){
610 asn1_delete_structure(element);
611 return ASN1_ERROR_TYPE_ANY;
613 else{
614 p2=p->down;
615 asn1_delete_structure(&p2);
619 if(p->down==NULL){
620 if(!(p->type&CONST_OPTION)){
621 asn1_delete_structure(element);
622 return ASN1_DER_ERROR;
625 else
626 p=p->down;
629 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
630 p2=_asn1_find_up(p);
631 len2=strtol(p2->value,NULL,10);
632 if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
635 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
636 if(ris!=ASN1_SUCCESS){
637 if(p->type&CONST_OPTION){
638 p->type|=CONST_NOT_USED;
639 move=RIGHT;
641 else if(p->type&CONST_DEFAULT) {
642 _asn1_set_value(p,NULL,0);
643 move=RIGHT;
645 else {
646 if (errorDescription!=NULL)
647 _asn1_error_description_tag_error(p,errorDescription);
649 asn1_delete_structure(element);
650 return ASN1_TAG_ERROR;
653 else counter+=len2;
656 if(ris==ASN1_SUCCESS){
657 switch(type_field(p->type)){
658 case TYPE_NULL:
659 if(der[counter]){
660 asn1_delete_structure(element);
661 return ASN1_DER_ERROR;
663 counter++;
664 move=RIGHT;
665 break;
666 case TYPE_BOOLEAN:
667 if(der[counter++]!=1){
668 asn1_delete_structure(element);
669 return ASN1_DER_ERROR;
671 if(der[counter++]==0) _asn1_set_value(p,"F",1);
672 else _asn1_set_value(p,"T",1);
673 move=RIGHT;
674 break;
675 case TYPE_INTEGER: case TYPE_ENUMERATED:
676 len2=_asn1_get_length_der(der+counter,&len3);
677 _asn1_set_value(p,der+counter,len3+len2);
678 counter+=len3+len2;
679 move=RIGHT;
680 break;
681 case TYPE_OBJECT_ID:
682 _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
683 _asn1_set_value(p,temp,strlen(temp)+1);
684 counter+=len2;
685 move=RIGHT;
686 break;
687 case TYPE_TIME:
688 _asn1_get_time_der(der+counter,&len2,temp);
689 _asn1_set_value(p,temp,strlen(temp)+1);
690 counter+=len2;
691 move=RIGHT;
692 break;
693 case TYPE_OCTET_STRING:
694 len3=len-counter;
695 ris=_asn1_get_octet_string(der+counter,p,&len3);
696 if(ris != ASN1_SUCCESS) return ris;
697 counter+=len3;
698 move=RIGHT;
699 break;
700 case TYPE_GENERALSTRING:
701 len2=_asn1_get_length_der(der+counter,&len3);
702 _asn1_set_value(p,der+counter,len3+len2);
703 counter+=len3+len2;
704 move=RIGHT;
705 break;
706 case TYPE_BIT_STRING:
707 len2=_asn1_get_length_der(der+counter,&len3);
708 _asn1_set_value(p,der+counter,len3+len2);
709 counter+=len3+len2;
710 move=RIGHT;
711 break;
712 case TYPE_SEQUENCE: case TYPE_SET:;
713 if(move==UP){
714 len2=strtol(p->value,NULL,10);
715 _asn1_set_value(p,NULL,0);
716 if(len2==-1){ /* indefinite length method */
717 if((der[counter]) || der[counter+1]){
718 asn1_delete_structure(element);
719 return ASN1_DER_ERROR;
721 counter+=2;
723 else{ /* definite length method */
724 if(len2!=counter){
725 asn1_delete_structure(element);
726 return ASN1_DER_ERROR;
729 move=RIGHT;
731 else{ /* move==DOWN || move==RIGHT */
732 len3=_asn1_get_length_der(der+counter,&len2);
733 counter+=len2;
734 if(len3>0){
735 _asn1_ltostr(counter+len3,temp);
736 _asn1_set_value(p,temp,strlen(temp)+1);
737 move=DOWN;
739 else if(len3==0){
740 p2=p->down;
741 while(p2){
742 if(type_field(p2->type)!=TYPE_TAG){
743 p3=p2->right;
744 asn1_delete_structure(&p2);
745 p2=p3;
747 else
748 p2=p2->right;
750 move=RIGHT;
752 else{ /* indefinite length method */
753 _asn1_set_value(p,"-1",3);
754 move=DOWN;
757 break;
758 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
759 if(move==UP){
760 len2=strtol(p->value,NULL,10);
761 if(len2==-1){ /* indefinite length method */
762 if((counter+2)>len) return ASN1_DER_ERROR;
763 if((der[counter]) || der[counter+1]){
764 _asn1_append_sequence_set(p);
765 p=p->down;
766 while(p->right) p=p->right;
767 move=RIGHT;
768 continue;
770 _asn1_set_value(p,NULL,0);
771 counter+=2;
773 else{ /* definite length method */
774 if(len2>counter){
775 _asn1_append_sequence_set(p);
776 p=p->down;
777 while(p->right) p=p->right;
778 move=RIGHT;
779 continue;
781 _asn1_set_value(p,NULL,0);
782 if(len2!=counter){
783 asn1_delete_structure(element);
784 return ASN1_DER_ERROR;
788 else{ /* move==DOWN || move==RIGHT */
789 len3=_asn1_get_length_der(der+counter,&len2);
790 counter+=len2;
791 if(len3){
792 if(len3>0){ /* definite length method */
793 _asn1_ltostr(counter+len3,temp);
794 _asn1_set_value(p,temp,strlen(temp)+1);
796 else { /* indefinite length method */
797 _asn1_set_value(p,"-1",3);
799 p2=p->down;
800 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
801 if(p2->right==NULL) _asn1_append_sequence_set(p);
802 p=p2;
805 move=RIGHT;
806 break;
807 case TYPE_ANY:
808 /* Check indefinite lenth method in a EXPLICIT TAG */
809 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
810 indefinite=1;
811 else
812 indefinite=0;
814 tag=_asn1_get_tag_der(der+counter,&class,&len2);
815 len4=_asn1_get_length_der(der+counter+len2,&len3);
817 if(len4 != -1){
818 len2+=len4;
819 _asn1_length_der(len2+len3,NULL,&len4);
820 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
821 if (temp2==NULL){
822 asn1_delete_structure(element);
823 return ASN1_MEM_ALLOC_ERROR;
826 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
827 _asn1_set_value(p,temp2,len4);
828 _asn1_afree(temp2);
829 counter+=len2+len3;
831 else{ /* indefinite length */
832 len2=len-counter;
833 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
834 if(ris != ASN1_SUCCESS){
835 asn1_delete_structure(element);
836 return ris;
838 _asn1_length_der(len2,NULL,&len4);
839 temp2=(unsigned char *)_asn1_alloca(len2+len4);
840 if (temp2==NULL){
841 asn1_delete_structure(element);
842 return ASN1_MEM_ALLOC_ERROR;
845 _asn1_octet_der(der+counter,len2,temp2,&len4);
846 _asn1_set_value(p,temp2,len4);
847 _asn1_afree(temp2);
848 counter+=len2;
851 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
852 a indefinite length method. */
853 if(indefinite){
854 if(!der[counter] && !der[counter+1]){
855 counter+=2;
857 else{
858 asn1_delete_structure(element);
859 return ASN1_DER_ERROR;
862 move=RIGHT;
863 break;
864 default:
865 move=(move==UP)?RIGHT:DOWN;
866 break;
870 if(p==node && move!=DOWN) break;
872 if(move==DOWN){
873 if(p->down) p=p->down;
874 else move=RIGHT;
876 if((move==RIGHT) && !(p->type&CONST_SET)){
877 if(p->right) p=p->right;
878 else move=UP;
880 if(move==UP) p=_asn1_find_up(p);
883 _asn1_delete_not_used(*element);
885 if(counter != len){
886 asn1_delete_structure(element);
887 return ASN1_DER_ERROR;
890 return ASN1_SUCCESS;
894 #define FOUND 1
895 #define SAME_BRANCH 2
896 #define OTHER_BRANCH 3
897 #define EXIT 4
900 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
901 * @structure: pointer to an ASN1 structure
902 * @elementName: name of the element to fill
903 * @der: vector that contains the DER encoding of the whole structure.
904 * @len: number of bytes of *der: der[0]..der[len-1]
905 * @errorDescription: null-terminated string contains details when an arror accured.
907 * Description:
909 * Fill the element named ELEMENTNAME with values of a DER encoding string.
910 * The sructure must just be created with function 'create_stucture'.
911 * The DER vector must contain the encoding string of the whole STRUCTURE.
912 * If an error accurs during the decoding procedure, the *STRUCTURE is deleted
913 * and set equal to ASN1_TYPE_EMPTY.
915 * Returns:
917 * ASN1_SUCCESS\: DER encoding OK
919 * ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE_EMPTY or elementName == NULL.
921 * ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure STRUCTURE. *ELEMENT deleted.
924 asn1_retCode
925 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
926 const unsigned char *der,int len,char *errorDescription)
928 node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
929 char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
930 int nameLen=MAX_NAME_SIZE*10-1,state;
931 int counter,len2,len3,len4,move,ris;
932 unsigned char class,*temp2;
933 unsigned int tag;
934 int indefinite;
936 node=*structure;
938 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
940 if(elementName == NULL){
941 asn1_delete_structure(structure);
942 return ASN1_ELEMENT_NOT_FOUND;
945 if(node->type&CONST_OPTION){
946 asn1_delete_structure(structure);
947 return ASN1_GENERIC_ERROR;
950 if((*structure)->name){ /* Has *structure a name? */
951 nameLen-=strlen((*structure)->name);
952 if(nameLen>0) strcpy(currentName,(*structure)->name);
953 else{
954 asn1_delete_structure(structure);
955 return ASN1_MEM_ERROR;
957 if(!(strcmp(currentName,elementName))){
958 state=FOUND;
959 nodeFound=*structure;
961 else if(!memcmp(currentName,elementName,strlen(currentName)))
962 state=SAME_BRANCH;
963 else
964 state=OTHER_BRANCH;
966 else{ /* *structure doesn't have a name? */
967 currentName[0]=0;
968 if(elementName[0]==0){
969 state=FOUND;
970 nodeFound=*structure;
972 else{
973 state=SAME_BRANCH;
977 counter=0;
978 move=DOWN;
979 p=node;
980 while(1){
982 ris=ASN1_SUCCESS;
984 if(move!=UP){
985 if(p->type&CONST_SET){
986 p2=_asn1_find_up(p);
987 len2=strtol(p2->value,NULL,10);
988 if(counter==len2){
989 p=p2;
990 move=UP;
991 continue;
993 else if(counter>len2){
994 asn1_delete_structure(structure);
995 return ASN1_DER_ERROR;
997 p2=p2->down;
998 while(p2){
999 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
1000 if(type_field(p2->type)!=TYPE_CHOICE)
1001 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1002 else{
1003 p3=p2->down;
1004 while(p3){
1005 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1006 if(ris==ASN1_SUCCESS) break;
1007 p3=p3->right;
1010 if(ris==ASN1_SUCCESS){
1011 p2->type&=~CONST_NOT_USED;
1012 p=p2;
1013 break;
1016 p2=p2->right;
1018 if(p2==NULL){
1019 asn1_delete_structure(structure);
1020 return ASN1_DER_ERROR;
1024 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1025 p2=_asn1_find_up(p);
1026 len2=strtol(p2->value,NULL,10);
1027 if(counter==len2){
1028 if(p->right){
1029 p2=p->right;
1030 move=RIGHT;
1032 else move=UP;
1034 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
1036 p=p2;
1037 continue;
1041 if(type_field(p->type)==TYPE_CHOICE){
1042 while(p->down){
1043 if(counter<len)
1044 ris=_asn1_extract_tag_der(p->down,der+counter,&len2);
1045 else
1046 ris=ASN1_DER_ERROR;
1047 if(ris==ASN1_SUCCESS){
1048 while(p->down->right){
1049 p2=p->down->right;
1050 asn1_delete_structure(&p2);
1052 break;
1054 else if(ris==ASN1_ERROR_TYPE_ANY){
1055 asn1_delete_structure(structure);
1056 return ASN1_ERROR_TYPE_ANY;
1058 else{
1059 p2=p->down;
1060 asn1_delete_structure(&p2);
1064 if(p->down==NULL){
1065 if(!(p->type&CONST_OPTION)){
1066 asn1_delete_structure(structure);
1067 return ASN1_DER_ERROR;
1070 else
1071 p=p->down;
1074 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1075 p2=_asn1_find_up(p);
1076 len2=strtol(p2->value,NULL,10);
1077 if(counter>len2) ris=ASN1_TAG_ERROR;
1080 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1081 if(ris!=ASN1_SUCCESS){
1082 if(p->type&CONST_OPTION){
1083 p->type|=CONST_NOT_USED;
1084 move=RIGHT;
1086 else if(p->type&CONST_DEFAULT) {
1087 _asn1_set_value(p,NULL,0);
1088 move=RIGHT;
1090 else {
1091 if (errorDescription!=NULL)
1092 _asn1_error_description_tag_error(p,errorDescription);
1094 asn1_delete_structure(structure);
1095 return ASN1_TAG_ERROR;
1098 else counter+=len2;
1101 if(ris==ASN1_SUCCESS){
1102 switch(type_field(p->type)){
1103 case TYPE_NULL:
1104 if(der[counter]){
1105 asn1_delete_structure(structure);
1106 return ASN1_DER_ERROR;
1109 if(p==nodeFound) state=EXIT;
1111 counter++;
1112 move=RIGHT;
1113 break;
1114 case TYPE_BOOLEAN:
1115 if(der[counter++]!=1){
1116 asn1_delete_structure(structure);
1117 return ASN1_DER_ERROR;
1120 if(state==FOUND){
1121 if(der[counter++]==0) _asn1_set_value(p,"F",1);
1122 else _asn1_set_value(p,"T",1);
1124 if(p==nodeFound) state=EXIT;
1127 else
1128 counter++;
1130 move=RIGHT;
1131 break;
1132 case TYPE_INTEGER: case TYPE_ENUMERATED:
1133 len2=_asn1_get_length_der(der+counter,&len3);
1134 if(state==FOUND){
1135 _asn1_set_value(p,der+counter,len3+len2);
1137 if(p==nodeFound) state=EXIT;
1139 counter+=len3+len2;
1140 move=RIGHT;
1141 break;
1142 case TYPE_OBJECT_ID:
1143 if(state==FOUND){
1144 _asn1_get_objectid_der(der+counter,&len2, temp, sizeof(temp));
1145 _asn1_set_value(p,temp,strlen(temp)+1);
1147 if(p==nodeFound) state=EXIT;
1149 else{
1150 len2=_asn1_get_length_der(der+counter,&len3);
1151 len2+=len3;
1154 counter+=len2;
1155 move=RIGHT;
1156 break;
1157 case TYPE_TIME:
1158 if(state==FOUND){
1159 _asn1_get_time_der(der+counter,&len2,temp);
1160 _asn1_set_value(p,temp,strlen(temp)+1);
1162 if(p==nodeFound) state=EXIT;
1164 else{
1165 len2=_asn1_get_length_der(der+counter,&len3);
1166 len2+=len3;
1169 counter+=len2;
1170 move=RIGHT;
1171 break;
1172 case TYPE_OCTET_STRING:
1173 len3=len-counter;
1174 if(state==FOUND){
1175 ris=_asn1_get_octet_string(der+counter,p,&len3);
1176 if(p==nodeFound) state=EXIT;
1178 else
1179 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1181 if(ris != ASN1_SUCCESS) return ris;
1182 counter+=len3;
1183 move=RIGHT;
1184 break;
1185 case TYPE_GENERALSTRING:
1186 len2=_asn1_get_length_der(der+counter,&len3);
1187 if(state==FOUND){
1188 _asn1_set_value(p,der+counter,len3+len2);
1190 if(p==nodeFound) state=EXIT;
1192 counter+=len3+len2;
1193 move=RIGHT;
1194 break;
1195 case TYPE_BIT_STRING:
1196 len2=_asn1_get_length_der(der+counter,&len3);
1197 if(state==FOUND){
1198 _asn1_set_value(p,der+counter,len3+len2);
1200 if(p==nodeFound) state=EXIT;
1202 counter+=len3+len2;
1203 move=RIGHT;
1204 break;
1205 case TYPE_SEQUENCE: case TYPE_SET:
1206 if(move==UP){
1207 len2=strtol(p->value,NULL,10);
1208 _asn1_set_value(p,NULL,0);
1209 if(len2==-1){ /* indefinite length method */
1210 if((der[counter]) || der[counter+1]){
1211 asn1_delete_structure(structure);
1212 return ASN1_DER_ERROR;
1214 counter+=2;
1216 else{ /* definite length method */
1217 if(len2!=counter){
1218 asn1_delete_structure(structure);
1219 return ASN1_DER_ERROR;
1222 if(p==nodeFound) state=EXIT;
1223 move=RIGHT;
1225 else{ /* move==DOWN || move==RIGHT */
1226 if(state==OTHER_BRANCH){
1227 len3=_asn1_get_length_der(der+counter,&len2);
1228 counter+=len2+len3;
1229 move=RIGHT;
1231 else { /* state==SAME_BRANCH or state==FOUND */
1232 len3=_asn1_get_length_der(der+counter,&len2);
1233 counter+=len2;
1234 if(len3>0){
1235 _asn1_ltostr(counter+len3,temp);
1236 _asn1_set_value(p,temp,strlen(temp)+1);
1237 move=DOWN;
1239 else if(len3==0){
1240 p2=p->down;
1241 while(p2){
1242 if(type_field(p2->type)!=TYPE_TAG){
1243 p3=p2->right;
1244 asn1_delete_structure(&p2);
1245 p2=p3;
1247 else
1248 p2=p2->right;
1250 move=RIGHT;
1252 else{ /* indefinite length method */
1253 _asn1_set_value(p,"-1",3);
1254 move=DOWN;
1258 break;
1259 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1260 if(move==UP){
1261 len2=strtol(p->value,NULL,10);
1262 if(len2>counter){
1263 _asn1_append_sequence_set(p);
1264 p=p->down;
1265 while(p->right) p=p->right;
1266 move=RIGHT;
1267 continue;
1269 _asn1_set_value(p,NULL,0);
1270 if(len2!=counter){
1271 asn1_delete_structure(structure);
1272 return ASN1_DER_ERROR;
1275 if(p==nodeFound) state=EXIT;
1277 else{ /* move==DOWN || move==RIGHT */
1278 if(state==OTHER_BRANCH){
1279 len3=_asn1_get_length_der(der+counter,&len2);
1280 counter+=len2+len3;
1281 move=RIGHT;
1283 else{ /* state==FOUND or state==SAME_BRANCH */
1284 len3=_asn1_get_length_der(der+counter,&len2);
1285 counter+=len2;
1286 if(len3){
1287 _asn1_ltostr(counter+len3,temp);
1288 _asn1_set_value(p,temp,strlen(temp)+1);
1289 p2=p->down;
1290 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1291 if(p2->right==NULL) _asn1_append_sequence_set(p);
1292 p=p2;
1293 state=FOUND;
1298 break;
1299 case TYPE_ANY:
1300 /* Check indefinite lenth method in a EXPLICIT TAG */
1301 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1302 indefinite=1;
1303 else
1304 indefinite=0;
1306 tag=_asn1_get_tag_der(der+counter,&class,&len2);
1307 len4=_asn1_get_length_der(der+counter+len2,&len3);
1309 if(len4 != -1){
1310 len2+=len4;
1311 if(state==FOUND){
1312 _asn1_length_der(len2+len3,NULL,&len4);
1313 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
1314 if (temp2==NULL){
1315 asn1_delete_structure(structure);
1316 return ASN1_MEM_ALLOC_ERROR;
1319 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
1320 _asn1_set_value(p,temp2,len4);
1321 _asn1_afree(temp2);
1323 if(p==nodeFound) state=EXIT;
1325 counter+=len2+len3;
1327 else{ /* indefinite length */
1328 len2=len-counter;
1329 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1330 if(ris != ASN1_SUCCESS){
1331 asn1_delete_structure(structure);
1332 return ris;
1335 if(state==FOUND){
1336 _asn1_length_der(len2,NULL,&len4);
1337 temp2=(unsigned char *)_asn1_alloca(len2+len4);
1338 if (temp2==NULL){
1339 asn1_delete_structure(structure);
1340 return ASN1_MEM_ALLOC_ERROR;
1343 _asn1_octet_der(der+counter,len2,temp2,&len4);
1344 _asn1_set_value(p,temp2,len4);
1345 _asn1_afree(temp2);
1347 if(p==nodeFound) state=EXIT;
1350 counter+=len2;
1353 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1354 a indefinite length method. */
1355 if(indefinite){
1356 if(!der[counter] && !der[counter+1]){
1357 counter+=2;
1359 else{
1360 asn1_delete_structure(structure);
1361 return ASN1_DER_ERROR;
1364 move=RIGHT;
1365 break;
1367 default:
1368 move=(move==UP)?RIGHT:DOWN;
1369 break;
1373 if((p==node && move!=DOWN) || (state==EXIT)) break;
1375 if(move==DOWN){
1376 if(p->down){
1377 p=p->down;
1379 if(state != FOUND){
1380 nameLen-=strlen(p->name)+1;
1381 if(nameLen>0){
1382 if(currentName[0]) strcat(currentName,".");
1383 strcat(currentName,p->name);
1385 else{
1386 asn1_delete_structure(structure);
1387 return ASN1_MEM_ERROR;
1389 if(!(strcmp(currentName,elementName))){
1390 state=FOUND;
1391 nodeFound=p;
1393 else if(!memcmp(currentName,elementName,strlen(currentName)))
1394 state=SAME_BRANCH;
1395 else
1396 state=OTHER_BRANCH;
1399 else move=RIGHT;
1402 if((move==RIGHT) && !(p->type&CONST_SET)){
1403 if(p->right){
1404 p=p->right;
1406 if(state != FOUND){
1407 dot_p=char_p=currentName;
1408 while((char_p=strchr(char_p,'.'))){
1409 dot_p=char_p++;
1410 dot_p++;
1413 nameLen+=strlen(currentName)-(dot_p-currentName);
1414 *dot_p=0;
1416 nameLen-=strlen(p->name);
1417 if(nameLen>0) strcat(currentName,p->name);
1418 else{
1419 asn1_delete_structure(structure);
1420 return ASN1_MEM_ERROR;
1423 if(!(strcmp(currentName,elementName))){
1424 state=FOUND;
1425 nodeFound=p;
1427 else if(!memcmp(currentName,elementName,strlen(currentName)))
1428 state=SAME_BRANCH;
1429 else
1430 state=OTHER_BRANCH;
1433 else move=UP;
1436 if(move==UP){
1437 p=_asn1_find_up(p);
1439 if(state != FOUND){
1440 dot_p=char_p=currentName;
1441 while((char_p=strchr(char_p,'.'))){
1442 dot_p=char_p++;
1443 dot_p++;
1446 nameLen+=strlen(currentName)-(dot_p-currentName);
1447 *dot_p=0;
1449 if(!(strcmp(currentName,elementName))){
1450 state=FOUND;
1451 nodeFound=p;
1453 else if(!memcmp(currentName,elementName,strlen(currentName)))
1454 state=SAME_BRANCH;
1455 else
1456 state=OTHER_BRANCH;
1461 _asn1_delete_not_used(*structure);
1463 if(counter > len){
1464 asn1_delete_structure(structure);
1465 return ASN1_DER_ERROR;
1468 return ASN1_SUCCESS;
1474 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1475 * @element: pointer to an ASN1 element
1476 * @der: vector that contains the DER encoding.
1477 * @len: number of bytes of *der: der[0]..der[len-1]
1478 * @name_element: an element of NAME structure.
1479 * @start: the position of the first byte of NAME_ELEMENT decoding (der[*start])
1480 * @end: the position of the last byte of NAME_ELEMENT decoding (der[*end])
1481 * Description:
1483 * Find the start and end point of an element in a DER encoding string. I mean that if you
1484 * have a der encoding and you have already used the function "asn1_der_decoding" to fill a structure, it may
1485 * happen that you want to find the piece of string concerning an element of the structure.
1487 * Example: the sequence "tbsCertificate" inside an X509 certificate.
1489 * Returns:
1491 * ASN1_SUCCESS\: DER encoding OK
1493 * ASN1_ELEMENT_NOT_FOUND\: ELEMENT is ASN1_TYPE EMPTY or NAME_ELEMENT is not a valid element.
1495 * ASN1_TAG_ERROR,ASN1_DER_ERROR\: the der encoding doesn't match the structure ELEMENT.
1498 asn1_retCode
1499 asn1_der_decoding_startEnd(ASN1_TYPE element,const unsigned char *der,int len,
1500 const char *name_element,int *start, int *end)
1502 node_asn *node,*node_to_find,*p,*p2,*p3;
1503 int counter,len2,len3,len4,move,ris;
1504 unsigned char class;
1505 unsigned int tag;
1506 int indefinite;
1508 node=element;
1510 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1512 node_to_find=_asn1_find_node(node,name_element);
1514 if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
1516 if(node_to_find==node){
1517 *start=0;
1518 *end=len-1;
1519 return ASN1_SUCCESS;
1522 if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
1524 counter=0;
1525 move=DOWN;
1526 p=node;
1527 while(1){
1528 ris=ASN1_SUCCESS;
1530 if(move!=UP){
1531 if(p->type&CONST_SET){
1532 p2=_asn1_find_up(p);
1533 len2=strtol(p2->value,NULL,10);
1534 if(len2==-1){
1535 if(!der[counter] && !der[counter+1]){
1536 p=p2;
1537 move=UP;
1538 counter+=2;
1539 continue;
1542 else if(counter==len2){
1543 p=p2;
1544 move=UP;
1545 continue;
1547 else if(counter>len2) return ASN1_DER_ERROR;
1548 p2=p2->down;
1549 while(p2){
1550 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
1551 if(type_field(p2->type)!=TYPE_CHOICE)
1552 ris=_asn1_extract_tag_der(p2,der+counter,&len2);
1553 else{
1554 p3=p2->down;
1555 ris=_asn1_extract_tag_der(p3,der+counter,&len2);
1557 if(ris==ASN1_SUCCESS){
1558 p2->type&=~CONST_NOT_USED;
1559 p=p2;
1560 break;
1563 p2=p2->right;
1565 if(p2==NULL) return ASN1_DER_ERROR;
1568 if(p==node_to_find) *start=counter;
1570 if(type_field(p->type)==TYPE_CHOICE){
1571 p=p->down;
1572 ris=_asn1_extract_tag_der(p,der+counter,&len2);
1573 if(p==node_to_find) *start=counter;
1576 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2);
1577 if(ris!=ASN1_SUCCESS){
1578 if(p->type&CONST_OPTION){
1579 p->type|=CONST_NOT_USED;
1580 move=RIGHT;
1582 else if(p->type&CONST_DEFAULT) {
1583 move=RIGHT;
1585 else {
1586 return ASN1_TAG_ERROR;
1589 else counter+=len2;
1592 if(ris==ASN1_SUCCESS){
1593 switch(type_field(p->type)){
1594 case TYPE_NULL:
1595 if(der[counter]) return ASN1_DER_ERROR;
1596 counter++;
1597 move=RIGHT;
1598 break;
1599 case TYPE_BOOLEAN:
1600 if(der[counter++]!=1) return ASN1_DER_ERROR;
1601 counter++;
1602 move=RIGHT;
1603 break;
1604 case TYPE_INTEGER: case TYPE_ENUMERATED:
1605 len2=_asn1_get_length_der(der+counter,&len3);
1606 counter+=len3+len2;
1607 move=RIGHT;
1608 break;
1609 case TYPE_OBJECT_ID:
1610 len2=_asn1_get_length_der(der+counter,&len3);
1611 counter+=len2+len3;
1612 move=RIGHT;
1613 break;
1614 case TYPE_TIME:
1615 len2=_asn1_get_length_der(der+counter,&len3);
1616 counter+=len2+len3;
1617 move=RIGHT;
1618 break;
1619 case TYPE_OCTET_STRING:
1620 len3=len-counter;
1621 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1622 if(ris != ASN1_SUCCESS) return ris;
1623 counter+=len3;
1624 move=RIGHT;
1625 break;
1626 case TYPE_GENERALSTRING:
1627 len2=_asn1_get_length_der(der+counter,&len3);
1628 counter+=len3+len2;
1629 move=RIGHT;
1630 break;
1631 case TYPE_BIT_STRING:
1632 len2=_asn1_get_length_der(der+counter,&len3);
1633 counter+=len3+len2;
1634 move=RIGHT;
1635 break;
1636 case TYPE_SEQUENCE: case TYPE_SET:
1637 if(move!=UP){
1638 len3=_asn1_get_length_der(der+counter,&len2);
1639 counter+=len2;
1640 if(len3==0) move=RIGHT;
1641 else move=DOWN;
1643 else{
1644 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1645 counter+=2;
1646 move=RIGHT;
1648 break;
1649 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1650 if(move!=UP){
1651 len3=_asn1_get_length_der(der+counter,&len2);
1652 counter+=len2;
1653 if((len3==-1) && !der[counter] && !der[counter+1])
1654 counter+=2;
1655 else if(len3){
1656 p2=p->down;
1657 while((type_field(p2->type)==TYPE_TAG) ||
1658 (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1659 p=p2;
1662 else{
1663 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1664 counter+=2;
1666 move=RIGHT;
1667 break;
1668 case TYPE_ANY:
1669 /* Check indefinite lenth method in a EXPLICIT TAG */
1670 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1671 indefinite=1;
1672 else
1673 indefinite=0;
1675 tag=_asn1_get_tag_der(der+counter,&class,&len2);
1676 len4=_asn1_get_length_der(der+counter+len2,&len3);
1678 if(len4 != -1){
1679 counter+=len2+len4+len3;
1681 else{ /* indefinite length */
1682 len2=len-counter;
1683 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1684 if(ris != ASN1_SUCCESS)
1685 return ris;
1686 counter+=len2;
1689 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1690 a indefinite length method. */
1691 if(indefinite){
1692 if(!der[counter] && !der[counter+1])
1693 counter+=2;
1694 else
1695 return ASN1_DER_ERROR;
1697 move=RIGHT;
1698 break;
1699 default:
1700 move=(move==UP)?RIGHT:DOWN;
1701 break;
1705 if((p==node_to_find) && (move==RIGHT)){
1706 *end=counter-1;
1707 return ASN1_SUCCESS;
1710 if(p==node && move!=DOWN) break;
1712 if(move==DOWN){
1713 if(p->down) p=p->down;
1714 else move=RIGHT;
1716 if((move==RIGHT) && !(p->type&CONST_SET)){
1717 if(p->right) p=p->right;
1718 else move=UP;
1720 if(move==UP) p=_asn1_find_up(p);
1723 return ASN1_ELEMENT_NOT_FOUND;
1728 * asn1_expand_any_defined_by - Expand every "ANY DEFINED BY" fields of
1729 * structure *ELEMENT with the corresponding type.
1730 * @definitions: ASN1 definitions
1731 * @element: pointer to an ASN1 structure
1732 * Description:
1734 * Expands every "ANY DEFINED BY" element of a structure created from
1735 * a DER decoding process (asn1_der_decoding function). The element ANY
1736 * must be defined by an OBJECT IDENTIFIER. The type used to expand
1737 * the element ANY is the first one following the definition of
1738 * the actual value of the OBJECT IDENTIFIER.
1741 * Returns:
1743 * ASN1_SUCCESS\: substitution OK
1745 * ASN1_ERROR_TYPE_ANY\: some "ANY DEFINED BY" element couldn't be expanded
1746 * due to a problem in OBJECT_ID -> TYPE association.
1747 * other errors\: result of der decoding process.
1750 asn1_retCode
1751 asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
1753 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1754 asn1_retCode retCode=ASN1_SUCCESS,result;
1755 int len,len2,len3;
1756 ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
1757 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1759 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1760 return ASN1_ELEMENT_NOT_FOUND;
1762 strcpy(definitionsName,definitions->name);
1763 strcat(definitionsName,".");
1765 p=*element;
1766 while(p){
1768 switch(type_field(p->type)){
1769 case TYPE_ANY:
1770 if((p->type&CONST_DEFINED_BY) && (p->value)){
1771 /* search the "DEF_BY" element */
1772 p2=p->down;
1773 while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
1774 p2=p2->right;
1776 if(!p2){
1777 retCode=ASN1_ERROR_TYPE_ANY;
1778 break;
1781 p3=_asn1_find_up(p);
1783 if(!p3){
1784 retCode=ASN1_ERROR_TYPE_ANY;
1785 break;
1788 p3=p3->down;
1789 while(p3){
1790 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1791 p3=p3->right;
1794 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1795 (p3->value==NULL)){
1797 p3=_asn1_find_up(p);
1798 p3=_asn1_find_up(p3);
1800 if(!p3){
1801 retCode=ASN1_ERROR_TYPE_ANY;
1802 break;
1805 p3=p3->down;
1807 while(p3){
1808 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1809 p3=p3->right;
1812 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1813 (p3->value==NULL)){
1814 retCode=ASN1_ERROR_TYPE_ANY;
1815 break;
1819 /* search the OBJECT_ID into definitions */
1820 p2=definitions->down;
1821 while(p2){
1822 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
1823 (p2->type & CONST_ASSIGN)){
1824 strcpy(name,definitionsName);
1825 strcat(name,p2->name);
1827 len=MAX_NAME_SIZE;
1828 result=asn1_read_value(definitions,name,value,&len);
1830 if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
1831 p2=p2->right; /* pointer to the structure to
1832 use for expansion */
1833 while((p2) && (p2->type & CONST_ASSIGN))
1834 p2=p2->right;
1836 if(p2){
1837 strcpy(name,definitionsName);
1838 strcat(name,p2->name);
1840 result=asn1_create_element(definitions,name,&aux);
1841 if(result == ASN1_SUCCESS){
1842 _asn1_set_name(aux,p->name);
1843 len2=_asn1_get_length_der(p->value,&len3);
1845 result=asn1_der_decoding(&aux,p->value+len3,len2,
1846 errorDescription);
1847 if(result == ASN1_SUCCESS){
1849 _asn1_set_right(aux,p->right);
1850 _asn1_set_right(p,aux);
1852 result=asn1_delete_structure(&p);
1853 if(result == ASN1_SUCCESS){
1854 p=aux;
1855 aux=ASN1_TYPE_EMPTY;
1856 break;
1858 else{ /* error with asn1_delete_structure */
1859 asn1_delete_structure(&aux);
1860 retCode=result;
1861 break;
1864 else{/* error with asn1_der_decoding */
1865 retCode=result;
1866 break;
1869 else{/* error with asn1_create_element */
1870 retCode=result;
1871 break;
1874 else{/* error with the pointer to the structure to exapand */
1875 retCode=ASN1_ERROR_TYPE_ANY;
1876 break;
1880 p2=p2->right;
1881 } /* end while */
1883 if(!p2){
1884 retCode=ASN1_ERROR_TYPE_ANY;
1885 break;
1889 break;
1890 default:
1891 break;
1895 if(p->down){
1896 p=p->down;
1898 else if(p==*element){
1899 p=NULL;
1900 break;
1902 else if(p->right) p=p->right;
1903 else{
1904 while(1){
1905 p=_asn1_find_up(p);
1906 if(p==*element){
1907 p=NULL;
1908 break;
1910 if(p->right){
1911 p=p->right;
1912 break;
1918 return retCode;
1924 * asn1_expand_octet_string - Expand an "OCTET STRING" fields of
1925 * structure *ELEMENT with the corresponding type.
1926 * @definitions: ASN1 definitions
1927 * @element: pointer to an ASN1 structure
1928 * @octetName: name of the OCTECT STRING field to expand.
1929 * @objectName: name of the OBJECT IDENTIFIER field to use to define
1930 * the type for expansion.
1932 * Description:
1934 * Expands an "OCTET STRING" element of a structure created from
1935 * a DER decoding process (asn1_der_decoding function). The type used
1936 * for expansion is the first one following the definition of
1937 * the actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
1939 * Returns:
1941 * ASN1_SUCCESS\: substitution OK
1943 * ASN1_ELEMENT_NOT_FOUND\: OBJECTNAME or OCTETNAME are not correct.
1945 * ASN1_VALUE_NOT_VALID\: wasn't possible to find the type to use
1946 * for expansion.
1948 * other errors\: result of der decoding process.
1950 asn1_retCode
1951 asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
1952 const char *octetName,const char *objectName)
1954 char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1955 asn1_retCode retCode=ASN1_SUCCESS,result;
1956 int len,len2,len3;
1957 ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
1958 ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
1959 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1961 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1962 return ASN1_ELEMENT_NOT_FOUND;
1964 octetNode=_asn1_find_node(*element,octetName);
1965 if(octetNode==ASN1_TYPE_EMPTY)
1966 return ASN1_ELEMENT_NOT_FOUND;
1967 if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
1968 return ASN1_ELEMENT_NOT_FOUND;
1969 if(octetNode->value==NULL)
1970 return ASN1_VALUE_NOT_FOUND;
1972 objectNode=_asn1_find_node(*element,objectName);
1973 if(objectNode==ASN1_TYPE_EMPTY)
1974 return ASN1_ELEMENT_NOT_FOUND;
1976 if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
1977 return ASN1_ELEMENT_NOT_FOUND;
1979 if(objectNode->value==NULL)
1980 return ASN1_VALUE_NOT_FOUND;
1983 /* search the OBJECT_ID into definitions */
1984 p2=definitions->down;
1985 while(p2){
1986 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
1987 (p2->type & CONST_ASSIGN)){
1988 strcpy(name,definitions->name);
1989 strcat(name,".");
1990 strcat(name,p2->name);
1992 len = sizeof(value);
1993 result=asn1_read_value(definitions,name,value,&len);
1995 if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
1997 p2=p2->right; /* pointer to the structure to
1998 use for expansion */
1999 while((p2) && (p2->type & CONST_ASSIGN))
2000 p2=p2->right;
2002 if(p2){
2003 strcpy(name,definitions->name);
2004 strcat(name,".");
2005 strcat(name,p2->name);
2007 result=asn1_create_element(definitions,name,&aux);
2008 if(result == ASN1_SUCCESS){
2009 _asn1_set_name(aux,octetNode->name);
2010 len2=_asn1_get_length_der(octetNode->value,&len3);
2012 result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
2013 errorDescription);
2014 if(result == ASN1_SUCCESS){
2016 _asn1_set_right(aux,octetNode->right);
2017 _asn1_set_right(octetNode,aux);
2019 result=asn1_delete_structure(&octetNode);
2020 if(result == ASN1_SUCCESS){
2021 aux=ASN1_TYPE_EMPTY;
2022 break;
2024 else{ /* error with asn1_delete_structure */
2025 asn1_delete_structure(&aux);
2026 retCode=result;
2027 break;
2030 else{/* error with asn1_der_decoding */
2031 retCode=result;
2032 break;
2035 else{/* error with asn1_create_element */
2036 retCode=result;
2037 break;
2040 else{/* error with the pointer to the structure to exapand */
2041 retCode=ASN1_VALUE_NOT_VALID;
2042 break;
2047 p2=p2->right;
2051 if(!p2) retCode=ASN1_VALUE_NOT_VALID;
2053 return retCode;