Doc fix for asn1_get_length_der.
[libtasn1.git] / lib / decoding.c
blobc267582cd1f291dc22e4c6fe026df99d180b542d
1 /*
2 * Copyright (C) 2004, 2006 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
5 * This file is part of LIBTASN1.
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
24 /*****************************************************/
25 /* File: decoding.c */
26 /* Description: Functions to manage DER decoding */
27 /*****************************************************/
29 #include <int.h>
30 #include <errors.h>
31 #include "der.h"
32 #include "parser_aux.h"
33 #include <gstr.h>
34 #include "structure.h"
35 #include "element.h"
38 void
39 _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
42 Estrcpy(ErrorDescription,":: tag error near element '");
43 _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
44 MAX_ERROR_DESCRIPTION_SIZE-40);
45 Estrcat(ErrorDescription,"'");
49 /**
50 * asn1_get_length_der:
51 * @der: DER data to decode.
52 * @der_len: Length of DER data to decode.
53 * @len: Output variable containing the length of the DER length field.
55 * Extract a length field from DER data.
57 * Return value: Return the decoded length value, or -1 on indefinite
58 * length, or -2 when the value was too big.
59 **/
60 signed long
61 asn1_get_length_der(const unsigned char *der, int der_len, int *len)
63 unsigned long ans;
64 int k,punt;
66 *len = 0;
67 if (der_len <= 0) return 0;
69 if(!(der[0]&128)){
70 /* short form */
71 *len=1;
72 return der[0];
74 else{
75 /* Long form */
76 k=der[0]&0x7F;
77 punt=1;
78 if(k){ /* definite length method */
79 ans=0;
80 while(punt<=k && punt < der_len) {
81 unsigned long last = ans;
83 ans=ans*256+der[punt++];
84 if (ans < last)
85 /* we wrapped around, no bignum support... */
86 return -2;
89 else{ /* indefinite length method */
90 ans=-1;
93 *len=punt;
94 return ans;
102 * asn1_get_tag_der:
103 * @der: DER data to decode.
104 * @der_len: Length of DER data to decode.
105 * @class: Output variable containing decoded class.
106 * @len: Output variable containing the length of the DER TAG data.
107 * @tag: Output variable containing the decoded tag.
109 * Decode the class and TAG from DER code.
111 * Return value: Returns ASN1_SUCCESS on success, or an error.
114 asn1_get_tag_der(const unsigned char *der, int der_len,
115 unsigned char *class,int *len, unsigned long *tag)
117 int punt,ris;
119 if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR;
121 *class=der[0]&0xE0;
122 if((der[0]&0x1F)!=0x1F){
123 /* short form */
124 *len=1;
125 ris=der[0]&0x1F;
127 else{
128 /* Long form */
129 punt=1;
130 ris=0;
131 while(punt <= der_len && der[punt]&128)
133 int last = ris;
134 ris=ris*128+(der[punt++]&0x7F);
135 if (ris < last)
136 /* wrapper around, and no bignums... */
137 return ASN1_DER_ERROR;
139 if (punt >= der_len)
140 return ASN1_DER_ERROR;
142 int last = ris;
143 ris=ris*128+(der[punt++]&0x7F);
144 if (ris < last)
145 /* wrapper around, and no bignums... */
146 return ASN1_DER_ERROR;
148 *len=punt;
150 if (tag) *tag = ris;
151 return ASN1_SUCCESS;
158 * asn1_get_octet_der:
159 * @der: DER data to decode containing the OCTET SEQUENCE.
160 * @der_len: Length of DER data to decode.
161 * @ret_len: Output variable containing the length of the DER data.
162 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
163 * @str_size: Length of pre-allocated output buffer.
164 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
166 * Extract an OCTET SEQUENCE from DER data.
168 * Return value: Returns ASN1_SUCCESS on success, or an error.
171 asn1_get_octet_der(const unsigned char *der, int der_len,
172 int *ret_len,unsigned char *str, int str_size, int *str_len)
174 int len_len;
176 if (der_len <= 0) return ASN1_GENERIC_ERROR;
178 /* if(str==NULL) return ASN1_SUCCESS; */
179 *str_len=asn1_get_length_der(der, der_len, &len_len);
181 if (*str_len < 0)
182 return ASN1_DER_ERROR;
184 *ret_len=*str_len+len_len;
185 if ( str_size >= *str_len)
186 memcpy(str,der+len_len,*str_len);
187 else {
188 return ASN1_MEM_ERROR;
191 return ASN1_SUCCESS;
196 /* Returns ASN1_SUCCESS on success or an error code on error.
199 _asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size)
201 int len_len,str_len;
203 if(der_len <=0 || str==NULL) return ASN1_DER_ERROR;
204 str_len=asn1_get_length_der(der, der_len, &len_len);
205 if (str_len < 0 || str_size < str_len)
206 return ASN1_DER_ERROR;
207 memcpy(str,der+len_len,str_len);
208 str[str_len]=0;
209 *ret_len=str_len+len_len;
211 return ASN1_SUCCESS;
216 void
217 _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size)
219 int len_len,len,k;
220 char temp[20];
221 unsigned long val,val1;
223 *ret_len = 0;
224 if (str && str_size > 0) str[0] = 0; /* no oid */
226 if(str==NULL || der_len <= 0) return;
227 len=asn1_get_length_der(der,der_len, &len_len);
229 if (len < 0 || len > der_len || len_len > der_len) return;
231 val1=der[len_len]/40;
232 val=der[len_len]-val1*40;
234 _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
235 _asn1_str_cat(str, str_size, ".");
236 _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
238 val=0;
239 for(k=1;k<len;k++){
240 val=val<<7;
241 val|=der[len_len+k]&0x7F;
242 if(!(der[len_len+k]&0x80)){
243 _asn1_str_cat(str, str_size,".");
244 _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
245 val=0;
248 *ret_len=len+len_len;
255 * asn1_get_bit_der:
256 * @der: DER data to decode containing the BIT SEQUENCE.
257 * @der_len: Length of DER data to decode.
258 * @ret_len: Output variable containing the length of the DER data.
259 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
260 * @str_size: Length of pre-allocated output buffer.
261 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
263 * Extract a BIT SEQUENCE from DER data.
265 * Return value: Return ASN1_SUCCESS on success, or an error.
268 asn1_get_bit_der(const unsigned char *der, int der_len,
269 int *ret_len, unsigned char *str, int str_size, int *bit_len)
271 int len_len,len_byte;
273 if (der_len <=0) return ASN1_GENERIC_ERROR;
274 len_byte=asn1_get_length_der(der,der_len,&len_len)-1;
275 if (len_byte < 0)
276 return ASN1_DER_ERROR;
278 *ret_len=len_byte+len_len+1;
279 *bit_len=len_byte*8-der[len_len];
281 if (str_size >= len_byte)
282 memcpy(str,der+len_len+1,len_byte);
283 else {
284 return ASN1_MEM_ERROR;
287 return ASN1_SUCCESS;
294 _asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len)
296 node_asn *p;
297 int counter,len2,len3,is_tag_implicit;
298 unsigned long tag,tag_implicit=0;
299 unsigned char class,class2,class_implicit=0;
301 if (der_len <= 0) return ASN1_GENERIC_ERROR;
303 counter=is_tag_implicit=0;
305 if(node->type&CONST_TAG){
306 p=node->down;
307 while(p){
308 if(type_field(p->type)==TYPE_TAG){
309 if(p->type&CONST_APPLICATION) class2=APPLICATION;
310 else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
311 else if(p->type&CONST_PRIVATE) class2=PRIVATE;
312 else class2=CONTEXT_SPECIFIC;
314 if(p->type&CONST_EXPLICIT){
315 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
316 return ASN1_DER_ERROR;
317 if (counter+len2 > der_len)
318 return ASN1_DER_ERROR;
319 counter+=len2;
320 len3=asn1_get_length_der(der+counter,der_len-counter, &len2);
321 if (len3 < 0)
322 return ASN1_DER_ERROR;
323 counter+=len2;
324 if(!is_tag_implicit){
325 if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
326 return ASN1_TAG_ERROR;
328 else{ /* TAG_IMPLICIT */
329 if((class!=class_implicit) || (tag!=tag_implicit))
330 return ASN1_TAG_ERROR;
333 is_tag_implicit=0;
335 else{ /* TAG_IMPLICIT */
336 if(!is_tag_implicit){
337 if((type_field(node->type)==TYPE_SEQUENCE) ||
338 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
339 (type_field(node->type)==TYPE_SET) ||
340 (type_field(node->type)==TYPE_SET_OF)) class2|=STRUCTURED;
341 class_implicit=class2;
342 tag_implicit=strtoul(p->value,NULL,10);
343 is_tag_implicit=1;
347 p=p->right;
351 if(is_tag_implicit){
352 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
353 return ASN1_DER_ERROR;
354 if (counter+len2 > der_len)
355 return ASN1_DER_ERROR;
357 if((class!=class_implicit) || (tag!=tag_implicit)){
358 if(type_field(node->type)==TYPE_OCTET_STRING){
359 class_implicit |= STRUCTURED;
360 if((class!=class_implicit) || (tag!=tag_implicit))
361 return ASN1_TAG_ERROR;
363 else
364 return ASN1_TAG_ERROR;
367 else{
368 if(type_field(node->type)==TYPE_TAG){
369 counter=0;
370 *ret_len=counter;
371 return ASN1_SUCCESS;
374 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
375 return ASN1_DER_ERROR;
376 if (counter+len2 > der_len)
377 return ASN1_DER_ERROR;
379 switch(type_field(node->type)){
380 case TYPE_NULL:
381 if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
382 break;
383 case TYPE_BOOLEAN:
384 if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
385 break;
386 case TYPE_INTEGER:
387 if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
388 break;
389 case TYPE_ENUMERATED:
390 if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
391 break;
392 case TYPE_OBJECT_ID:
393 if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
394 break;
395 case TYPE_TIME:
396 if(node->type&CONST_UTC){
397 if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
399 else{
400 if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime))
401 return ASN1_DER_ERROR;
403 break;
404 case TYPE_OCTET_STRING:
405 if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
406 || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
407 break;
408 case TYPE_GENERALSTRING:
409 if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
410 break;
411 case TYPE_BIT_STRING:
412 if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
413 break;
414 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
415 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE))
416 return ASN1_DER_ERROR;
417 break;
418 case TYPE_SET: case TYPE_SET_OF:
419 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET))
420 return ASN1_DER_ERROR;
421 break;
422 case TYPE_ANY:
423 counter-=len2;
424 break;
425 default:
426 return ASN1_DER_ERROR;
427 break;
431 counter+=len2;
432 *ret_len=counter;
433 return ASN1_SUCCESS;
437 int
438 _asn1_delete_not_used(node_asn *node)
440 node_asn *p,*p2;
442 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
444 p=node;
445 while(p){
446 if(p->type&CONST_NOT_USED){
447 p2=NULL;
448 if(p!=node){
449 p2=_asn1_find_left(p);
450 if(!p2) p2=_asn1_find_up(p);
452 asn1_delete_structure(&p);
453 p=p2;
456 if(!p) break; /* reach node */
458 if(p->down){
459 p=p->down;
461 else{
462 if(p==node) p=NULL;
463 else if(p->right) p=p->right;
464 else{
465 while(1){
466 p=_asn1_find_up(p);
467 if(p==node){
468 p=NULL;
469 break;
471 if(p->right){
472 p=p->right;
473 break;
479 return ASN1_SUCCESS;
483 asn1_retCode
484 _asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len)
486 int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
487 char *temp,*temp2;
489 counter=0;
491 if(*(der-1) & STRUCTURED){
492 tot_len=0;
493 indefinite=asn1_get_length_der(der, *len, &len3);
494 if (indefinite < -1)
495 return ASN1_DER_ERROR;
497 counter+=len3;
498 if(indefinite>=0) indefinite+=len3;
500 while(1){
501 if(counter>(*len)) return ASN1_DER_ERROR;
503 if(indefinite==-1){
504 if((der[counter]==0) && (der[counter+1]==0)){
505 counter+=2;
506 break;
509 else if(counter>=indefinite) break;
511 if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
513 counter++;
515 len2=asn1_get_length_der(der+counter,*len-counter, &len3);
516 if(len2 <= 0) return ASN1_DER_ERROR;
518 counter+=len3+len2;
519 tot_len+=len2;
522 /* copy */
523 if(node){
524 asn1_length_der(tot_len,NULL,&len2);
525 temp=(unsigned char *)_asn1_alloca(len2+tot_len);
526 if (temp==NULL){
527 return ASN1_MEM_ALLOC_ERROR;
530 asn1_length_der(tot_len,temp,&len2);
531 tot_len+=len2;
532 temp2=temp+len2;
533 len2=asn1_get_length_der(der,*len,&len3);
534 if(len2 < -1) return ASN1_DER_ERROR;
535 counter2=len3+1;
537 if(indefinite==-1) counter_end=counter-2;
538 else counter_end=counter;
540 while(counter2<counter_end){
541 len2=asn1_get_length_der(der+counter2, *len-counter, &len3);
542 if(len2 < -1) return ASN1_DER_ERROR;
544 /* FIXME: to be checked. Is this ok? Has the
545 * size been checked before?
547 memcpy(temp2,der+counter2+len3,len2);
548 temp2+=len2;
549 counter2+=len2+len3+1;
552 _asn1_set_value(node,temp,tot_len);
553 _asn1_afree(temp);
556 else{ /* NOT STRUCTURED */
557 len2=asn1_get_length_der(der, *len, &len3);
558 if(len2 < 0) return ASN1_DER_ERROR;
559 if (len3+len2 > *len) return ASN1_DER_ERROR;
560 if(node)
561 _asn1_set_value(node,der,len3+len2);
562 counter=len3+len2;
565 *len=counter;
566 return ASN1_SUCCESS;
571 asn1_retCode
572 _asn1_get_indefinite_length_string(const unsigned char* der, int* len)
574 int len2,len3,counter,indefinite;
575 unsigned long tag;
576 unsigned char class;
578 counter=indefinite=0;
580 while(1){
581 if((*len)<counter) return ASN1_DER_ERROR;
583 if((der[counter]==0) && (der[counter+1]==0)){
584 counter+=2;
585 indefinite--;
586 if(indefinite<=0) break;
587 else continue;
590 if(asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
591 return ASN1_DER_ERROR;
592 if (counter+len2 > *len)
593 return ASN1_DER_ERROR;
594 counter+=len2;
595 len2=asn1_get_length_der(der+counter, *len-counter,&len3);
596 if(len2 < -1) return ASN1_DER_ERROR;
597 if(len2 == -1){
598 indefinite++;
599 counter+=1;
601 else{
602 counter+=len2+len3;
606 *len=counter;
607 return ASN1_SUCCESS;
613 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
614 * @element: pointer to an ASN1 structure.
615 * @ider: vector that contains the DER encoding.
616 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
617 * @errorDescription: null-terminated string contains details when an
618 * error occurred.
620 * Fill the structure *ELEMENT with values of a DER encoding
621 * string. The sructure must just be created with function
622 * 'create_stucture'. If an error occurs during the decoding
623 * procedure, the *ELEMENT is deleted and set equal to
624 * %ASN1_TYPE_EMPTY.
626 * Returns:
628 * ASN1_SUCCESS: DER encoding OK.
630 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY.
632 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
633 * the structure NAME. *ELEMENT deleted.
636 asn1_retCode
637 asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
638 char *errorDescription)
640 node_asn *node,*p,*p2,*p3;
641 char temp[128];
642 int counter,len2,len3,len4,move,ris,tlen;
643 unsigned char class,*temp2;
644 unsigned long tag;
645 int indefinite, result;
646 const unsigned char* der = ider;
648 node=*element;
650 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
652 if(node->type&CONST_OPTION){
653 asn1_delete_structure(element);
654 return ASN1_GENERIC_ERROR;
657 counter=0;
658 move=DOWN;
659 p=node;
660 while(1){
661 ris=ASN1_SUCCESS;
662 if(move!=UP){
663 if(p->type&CONST_SET){
664 p2=_asn1_find_up(p);
665 len2=strtol(p2->value,NULL,10);
666 if(len2==-1){
667 if(!der[counter] && !der[counter+1]){
668 p=p2;
669 move=UP;
670 counter+=2;
671 continue;
674 else if(counter==len2){
675 p=p2;
676 move=UP;
677 continue;
679 else if(counter>len2){
680 asn1_delete_structure(element);
681 return ASN1_DER_ERROR;
683 p2=p2->down;
684 while(p2){
685 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
686 if(type_field(p2->type)!=TYPE_CHOICE)
687 ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2);
688 else{
689 p3=p2->down;
690 while(p3){
691 ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2);
692 if(ris==ASN1_SUCCESS) break;
693 p3=p3->right;
696 if(ris==ASN1_SUCCESS){
697 p2->type&=~CONST_NOT_USED;
698 p=p2;
699 break;
702 p2=p2->right;
704 if(p2==NULL){
705 asn1_delete_structure(element);
706 return ASN1_DER_ERROR;
710 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
711 p2=_asn1_find_up(p);
712 len2=strtol(p2->value,NULL,10);
713 if(counter==len2){
714 if(p->right){
715 p2=p->right;
716 move=RIGHT;
718 else move=UP;
720 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
722 p=p2;
723 continue;
727 if(type_field(p->type)==TYPE_CHOICE){
728 while(p->down){
729 if(counter<len)
730 ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
731 else
732 ris=ASN1_DER_ERROR;
733 if(ris==ASN1_SUCCESS){
734 while(p->down->right){
735 p2=p->down->right;
736 asn1_delete_structure(&p2);
738 break;
740 else if(ris==ASN1_ERROR_TYPE_ANY){
741 asn1_delete_structure(element);
742 return ASN1_ERROR_TYPE_ANY;
744 else{
745 p2=p->down;
746 asn1_delete_structure(&p2);
750 if(p->down==NULL){
751 if(!(p->type&CONST_OPTION)){
752 asn1_delete_structure(element);
753 return ASN1_DER_ERROR;
756 else
757 p=p->down;
760 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
761 p2=_asn1_find_up(p);
762 len2=strtol(p2->value,NULL,10);
763 if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
766 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
767 if(ris!=ASN1_SUCCESS){
768 if(p->type&CONST_OPTION){
769 p->type|=CONST_NOT_USED;
770 move=RIGHT;
772 else if(p->type&CONST_DEFAULT) {
773 _asn1_set_value(p,NULL,0);
774 move=RIGHT;
776 else {
777 if (errorDescription!=NULL)
778 _asn1_error_description_tag_error(p,errorDescription);
780 asn1_delete_structure(element);
781 return ASN1_TAG_ERROR;
784 else counter+=len2;
787 if(ris==ASN1_SUCCESS){
788 switch(type_field(p->type)){
789 case TYPE_NULL:
790 if(der[counter]){
791 asn1_delete_structure(element);
792 return ASN1_DER_ERROR;
794 counter++;
795 move=RIGHT;
796 break;
797 case TYPE_BOOLEAN:
798 if(der[counter++]!=1){
799 asn1_delete_structure(element);
800 return ASN1_DER_ERROR;
802 if(der[counter++]==0) _asn1_set_value(p,"F",1);
803 else _asn1_set_value(p,"T",1);
804 move=RIGHT;
805 break;
806 case TYPE_INTEGER: case TYPE_ENUMERATED:
807 len2=asn1_get_length_der(der+counter,len-counter, &len3);
808 if(len2 < 0) return ASN1_DER_ERROR;
809 if (len2+len3 > len-counter) return ASN1_DER_ERROR;
810 _asn1_set_value(p,der+counter,len3+len2);
811 counter+=len3+len2;
812 move=RIGHT;
813 break;
814 case TYPE_OBJECT_ID:
815 _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
816 tlen = strlen(temp);
817 if( tlen > 0)
818 _asn1_set_value(p,temp,tlen+1);
819 counter+=len2;
820 move=RIGHT;
821 break;
822 case TYPE_TIME:
823 result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
824 if (result != ASN1_SUCCESS) {
825 asn1_delete_structure(element);
826 return result;
828 tlen = strlen(temp);
829 if (tlen > 0)
830 _asn1_set_value(p,temp,tlen+1);
831 counter+=len2;
832 move=RIGHT;
833 break;
834 case TYPE_OCTET_STRING:
835 len3=len-counter;
836 ris=_asn1_get_octet_string(der+counter,p,&len3);
837 if(ris != ASN1_SUCCESS) return ris;
838 counter+=len3;
839 move=RIGHT;
840 break;
841 case TYPE_GENERALSTRING:
842 len2=asn1_get_length_der(der+counter,len-counter,&len3);
843 if(len2 < 0) return ASN1_DER_ERROR;
844 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
845 _asn1_set_value(p,der+counter,len3+len2);
846 counter+=len3+len2;
847 move=RIGHT;
848 break;
849 case TYPE_BIT_STRING:
850 len2=asn1_get_length_der(der+counter,len-counter,&len3);
851 if(len2 < 0) return ASN1_DER_ERROR;
852 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
853 _asn1_set_value(p,der+counter,len3+len2);
854 counter+=len3+len2;
855 move=RIGHT;
856 break;
857 case TYPE_SEQUENCE: case TYPE_SET:
858 if(move==UP){
859 len2=strtol(p->value,NULL,10);
860 _asn1_set_value(p,NULL,0);
861 if(len2==-1){ /* indefinite length method */
862 if (len-counter+1 > 0) {
863 if((der[counter]) || der[counter+1]){
864 asn1_delete_structure(element);
865 return ASN1_DER_ERROR;
867 } else return ASN1_DER_ERROR;
868 counter+=2;
870 else{ /* definite length method */
871 if(len2!=counter){
872 asn1_delete_structure(element);
873 return ASN1_DER_ERROR;
876 move=RIGHT;
878 else{ /* move==DOWN || move==RIGHT */
879 len3=asn1_get_length_der(der+counter,len-counter,&len2);
880 if(len3 < -1) return ASN1_DER_ERROR;
881 counter+=len2;
882 if(len3>0){
883 _asn1_ltostr(counter+len3,temp);
884 tlen = strlen(temp);
885 if (tlen > 0)
886 _asn1_set_value(p,temp,tlen+1);
887 move=DOWN;
889 else if(len3==0){
890 p2=p->down;
891 while(p2){
892 if(type_field(p2->type)!=TYPE_TAG){
893 p3=p2->right;
894 asn1_delete_structure(&p2);
895 p2=p3;
897 else
898 p2=p2->right;
900 move=RIGHT;
902 else{ /* indefinite length method */
903 _asn1_set_value(p,"-1",3);
904 move=DOWN;
907 break;
908 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
909 if(move==UP){
910 len2=strtol(p->value,NULL,10);
911 if(len2==-1){ /* indefinite length method */
912 if((counter+2)>len) return ASN1_DER_ERROR;
913 if((der[counter]) || der[counter+1]){
914 _asn1_append_sequence_set(p);
915 p=p->down;
916 while(p->right) p=p->right;
917 move=RIGHT;
918 continue;
920 _asn1_set_value(p,NULL,0);
921 counter+=2;
923 else{ /* definite length method */
924 if(len2>counter){
925 _asn1_append_sequence_set(p);
926 p=p->down;
927 while(p->right) p=p->right;
928 move=RIGHT;
929 continue;
931 _asn1_set_value(p,NULL,0);
932 if(len2!=counter){
933 asn1_delete_structure(element);
934 return ASN1_DER_ERROR;
938 else{ /* move==DOWN || move==RIGHT */
939 len3=asn1_get_length_der(der+counter,len-counter,&len2);
940 if(len3 < -1) return ASN1_DER_ERROR;
941 counter+=len2;
942 if(len3){
943 if(len3>0){ /* definite length method */
944 _asn1_ltostr(counter+len3,temp);
945 tlen = strlen(temp);
947 if (tlen > 0)
948 _asn1_set_value(p,temp,tlen+1);
950 else { /* indefinite length method */
951 _asn1_set_value(p,"-1",3);
953 p2=p->down;
954 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
955 if(p2->right==NULL) _asn1_append_sequence_set(p);
956 p=p2;
959 move=RIGHT;
960 break;
961 case TYPE_ANY:
962 if(asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
963 return ASN1_DER_ERROR;
964 if (counter+len2 > len)
965 return ASN1_DER_ERROR;
966 len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
967 if(len4 < -1) return ASN1_DER_ERROR;
968 if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR;
969 if(len4 != -1){
970 len2+=len4;
971 asn1_length_der(len2+len3,NULL,&len4);
972 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
973 if (temp2==NULL){
974 asn1_delete_structure(element);
975 return ASN1_MEM_ALLOC_ERROR;
978 asn1_octet_der(der+counter,len2+len3,temp2,&len4);
979 _asn1_set_value(p,temp2,len4);
980 _asn1_afree(temp2);
981 counter+=len2+len3;
983 else{ /* indefinite length */
984 /* Check indefinite lenth method in an EXPLICIT TAG */
985 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
986 indefinite=1;
987 else
988 indefinite=0;
990 len2=len-counter;
991 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
992 if(ris != ASN1_SUCCESS){
993 asn1_delete_structure(element);
994 return ris;
996 asn1_length_der(len2,NULL,&len4);
997 temp2=(unsigned char *)_asn1_alloca(len2+len4);
998 if (temp2==NULL){
999 asn1_delete_structure(element);
1000 return ASN1_MEM_ALLOC_ERROR;
1003 asn1_octet_der(der+counter,len2,temp2,&len4);
1004 _asn1_set_value(p,temp2,len4);
1005 _asn1_afree(temp2);
1006 counter+=len2;
1008 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1009 an indefinite length method. */
1010 if(indefinite){
1011 if(!der[counter] && !der[counter+1]){
1012 counter+=2;
1014 else{
1015 asn1_delete_structure(element);
1016 return ASN1_DER_ERROR;
1020 move=RIGHT;
1021 break;
1022 default:
1023 move=(move==UP)?RIGHT:DOWN;
1024 break;
1028 if(p==node && move!=DOWN) break;
1030 if(move==DOWN){
1031 if(p->down) p=p->down;
1032 else move=RIGHT;
1034 if((move==RIGHT) && !(p->type&CONST_SET)){
1035 if(p->right) p=p->right;
1036 else move=UP;
1038 if(move==UP) p=_asn1_find_up(p);
1041 _asn1_delete_not_used(*element);
1043 if(counter != len){
1044 asn1_delete_structure(element);
1045 return ASN1_DER_ERROR;
1048 return ASN1_SUCCESS;
1052 #define FOUND 1
1053 #define SAME_BRANCH 2
1054 #define OTHER_BRANCH 3
1055 #define EXIT 4
1058 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
1059 * @structure: pointer to an ASN1 structure
1060 * @elementName: name of the element to fill
1061 * @ider: vector that contains the DER encoding of the whole structure.
1062 * @len: number of bytes of *der: der[0]..der[len-1]
1063 * @errorDescription: null-terminated string contains details when an
1064 * error occurred.
1066 * Fill the element named ELEMENTNAME with values of a DER encoding
1067 * string. The sructure must just be created with function
1068 * 'create_stucture'. The DER vector must contain the encoding
1069 * string of the whole STRUCTURE. If an error occurs during the
1070 * decoding procedure, the *STRUCTURE is deleted and set equal to
1071 * %ASN1_TYPE_EMPTY.
1073 * Returns:
1075 * ASN1_SUCCESS: DER encoding OK.
1077 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or
1078 * elementName == NULL.
1080 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
1081 * the structure STRUCTURE. *ELEMENT deleted.
1084 asn1_retCode
1085 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
1086 const void *ider,int len,char *errorDescription)
1088 node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
1089 char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
1090 int nameLen=MAX_NAME_SIZE*10-1,state;
1091 int counter,len2,len3,len4,move,ris, tlen;
1092 unsigned char class,*temp2;
1093 unsigned long tag;
1094 int indefinite, result;
1095 const unsigned char* der = ider;
1097 node=*structure;
1099 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1101 if(elementName == NULL){
1102 asn1_delete_structure(structure);
1103 return ASN1_ELEMENT_NOT_FOUND;
1106 if(node->type&CONST_OPTION){
1107 asn1_delete_structure(structure);
1108 return ASN1_GENERIC_ERROR;
1111 if((*structure)->name){ /* Has *structure got a name? */
1112 nameLen-=strlen((*structure)->name);
1113 if(nameLen>0) strcpy(currentName,(*structure)->name);
1114 else{
1115 asn1_delete_structure(structure);
1116 return ASN1_MEM_ERROR;
1118 if(!(strcmp(currentName,elementName))){
1119 state=FOUND;
1120 nodeFound=*structure;
1122 else if(!memcmp(currentName,elementName,strlen(currentName)))
1123 state=SAME_BRANCH;
1124 else
1125 state=OTHER_BRANCH;
1127 else{ /* *structure doesn't have a name? */
1128 currentName[0]=0;
1129 if(elementName[0]==0){
1130 state=FOUND;
1131 nodeFound=*structure;
1133 else{
1134 state=SAME_BRANCH;
1138 counter=0;
1139 move=DOWN;
1140 p=node;
1141 while(1){
1143 ris=ASN1_SUCCESS;
1145 if(move!=UP){
1146 if(p->type&CONST_SET){
1147 p2=_asn1_find_up(p);
1148 len2=strtol(p2->value,NULL,10);
1149 if(counter==len2){
1150 p=p2;
1151 move=UP;
1152 continue;
1154 else if(counter>len2){
1155 asn1_delete_structure(structure);
1156 return ASN1_DER_ERROR;
1158 p2=p2->down;
1159 while(p2){
1160 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
1161 if(type_field(p2->type)!=TYPE_CHOICE)
1162 ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
1163 else{
1164 p3=p2->down;
1165 while(p3){
1166 ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
1167 if(ris==ASN1_SUCCESS) break;
1168 p3=p3->right;
1171 if(ris==ASN1_SUCCESS){
1172 p2->type&=~CONST_NOT_USED;
1173 p=p2;
1174 break;
1177 p2=p2->right;
1179 if(p2==NULL){
1180 asn1_delete_structure(structure);
1181 return ASN1_DER_ERROR;
1185 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1186 p2=_asn1_find_up(p);
1187 len2=strtol(p2->value,NULL,10);
1188 if(counter==len2){
1189 if(p->right){
1190 p2=p->right;
1191 move=RIGHT;
1193 else move=UP;
1195 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
1197 p=p2;
1198 continue;
1202 if(type_field(p->type)==TYPE_CHOICE){
1203 while(p->down){
1204 if(counter<len)
1205 ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
1206 else
1207 ris=ASN1_DER_ERROR;
1208 if(ris==ASN1_SUCCESS){
1209 while(p->down->right){
1210 p2=p->down->right;
1211 asn1_delete_structure(&p2);
1213 break;
1215 else if(ris==ASN1_ERROR_TYPE_ANY){
1216 asn1_delete_structure(structure);
1217 return ASN1_ERROR_TYPE_ANY;
1219 else{
1220 p2=p->down;
1221 asn1_delete_structure(&p2);
1225 if(p->down==NULL){
1226 if(!(p->type&CONST_OPTION)){
1227 asn1_delete_structure(structure);
1228 return ASN1_DER_ERROR;
1231 else
1232 p=p->down;
1235 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1236 p2=_asn1_find_up(p);
1237 len2=strtol(p2->value,NULL,10);
1238 if(counter>len2) ris=ASN1_TAG_ERROR;
1241 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
1242 if(ris!=ASN1_SUCCESS){
1243 if(p->type&CONST_OPTION){
1244 p->type|=CONST_NOT_USED;
1245 move=RIGHT;
1247 else if(p->type&CONST_DEFAULT) {
1248 _asn1_set_value(p,NULL,0);
1249 move=RIGHT;
1251 else {
1252 if (errorDescription!=NULL)
1253 _asn1_error_description_tag_error(p,errorDescription);
1255 asn1_delete_structure(structure);
1256 return ASN1_TAG_ERROR;
1259 else counter+=len2;
1262 if(ris==ASN1_SUCCESS){
1263 switch(type_field(p->type)){
1264 case TYPE_NULL:
1265 if(der[counter]){
1266 asn1_delete_structure(structure);
1267 return ASN1_DER_ERROR;
1270 if(p==nodeFound) state=EXIT;
1272 counter++;
1273 move=RIGHT;
1274 break;
1275 case TYPE_BOOLEAN:
1276 if(der[counter++]!=1){
1277 asn1_delete_structure(structure);
1278 return ASN1_DER_ERROR;
1281 if(state==FOUND){
1282 if(der[counter++]==0) _asn1_set_value(p,"F",1);
1283 else _asn1_set_value(p,"T",1);
1285 if(p==nodeFound) state=EXIT;
1288 else
1289 counter++;
1291 move=RIGHT;
1292 break;
1293 case TYPE_INTEGER: case TYPE_ENUMERATED:
1294 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1295 if(len2 < 0) return ASN1_DER_ERROR;
1296 if(state==FOUND){
1297 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
1298 _asn1_set_value(p,der+counter,len3+len2);
1300 if(p==nodeFound) state=EXIT;
1302 counter+=len3+len2;
1303 move=RIGHT;
1304 break;
1305 case TYPE_OBJECT_ID:
1306 if(state==FOUND){
1307 _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
1308 tlen = strlen(temp);
1310 if (tlen > 0)
1311 _asn1_set_value(p,temp,tlen+1);
1313 if(p==nodeFound) state=EXIT;
1315 else{
1316 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1317 if(len2 < 0) return ASN1_DER_ERROR;
1318 len2+=len3;
1321 counter+=len2;
1322 move=RIGHT;
1323 break;
1324 case TYPE_TIME:
1325 if(state==FOUND){
1326 result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
1327 if (result != ASN1_SUCCESS) {
1328 asn1_delete_structure(structure);
1329 return result;
1332 tlen = strlen(temp);
1333 if (tlen > 0)
1334 _asn1_set_value(p,temp,tlen+1);
1336 if(p==nodeFound) state=EXIT;
1338 else{
1339 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1340 if(len2 < 0) return ASN1_DER_ERROR;
1341 len2+=len3;
1344 counter+=len2;
1345 move=RIGHT;
1346 break;
1347 case TYPE_OCTET_STRING:
1348 len3=len-counter;
1349 if(state==FOUND){
1350 ris=_asn1_get_octet_string(der+counter,p,&len3);
1351 if(p==nodeFound) state=EXIT;
1353 else
1354 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1356 if(ris != ASN1_SUCCESS) return ris;
1357 counter+=len3;
1358 move=RIGHT;
1359 break;
1360 case TYPE_GENERALSTRING:
1361 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1362 if(len2 < 0) return ASN1_DER_ERROR;
1363 if(state==FOUND){
1364 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
1365 _asn1_set_value(p,der+counter,len3+len2);
1367 if(p==nodeFound) state=EXIT;
1369 counter+=len3+len2;
1370 move=RIGHT;
1371 break;
1372 case TYPE_BIT_STRING:
1373 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1374 if(len2 < 0) return ASN1_DER_ERROR;
1375 if(state==FOUND){
1376 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
1377 _asn1_set_value(p,der+counter,len3+len2);
1379 if(p==nodeFound) state=EXIT;
1381 counter+=len3+len2;
1382 move=RIGHT;
1383 break;
1384 case TYPE_SEQUENCE: case TYPE_SET:
1385 if(move==UP){
1386 len2=strtol(p->value,NULL,10);
1387 _asn1_set_value(p,NULL,0);
1388 if(len2==-1){ /* indefinite length method */
1389 if((der[counter]) || der[counter+1]){
1390 asn1_delete_structure(structure);
1391 return ASN1_DER_ERROR;
1393 counter+=2;
1395 else{ /* definite length method */
1396 if(len2!=counter){
1397 asn1_delete_structure(structure);
1398 return ASN1_DER_ERROR;
1401 if(p==nodeFound) state=EXIT;
1402 move=RIGHT;
1404 else{ /* move==DOWN || move==RIGHT */
1405 if(state==OTHER_BRANCH){
1406 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1407 if(len3 < 0) return ASN1_DER_ERROR;
1408 counter+=len2+len3;
1409 move=RIGHT;
1411 else { /* state==SAME_BRANCH or state==FOUND */
1412 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1413 if(len3 < 0) return ASN1_DER_ERROR;
1414 counter+=len2;
1415 if(len3>0){
1416 _asn1_ltostr(counter+len3,temp);
1417 tlen = strlen(temp);
1419 if(tlen > 0)
1420 _asn1_set_value(p,temp,tlen+1);
1421 move=DOWN;
1423 else if(len3==0){
1424 p2=p->down;
1425 while(p2){
1426 if(type_field(p2->type)!=TYPE_TAG){
1427 p3=p2->right;
1428 asn1_delete_structure(&p2);
1429 p2=p3;
1431 else
1432 p2=p2->right;
1434 move=RIGHT;
1436 else{ /* indefinite length method */
1437 _asn1_set_value(p,"-1",3);
1438 move=DOWN;
1442 break;
1443 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1444 if(move==UP){
1445 len2=strtol(p->value,NULL,10);
1446 if(len2>counter){
1447 _asn1_append_sequence_set(p);
1448 p=p->down;
1449 while(p->right) p=p->right;
1450 move=RIGHT;
1451 continue;
1453 _asn1_set_value(p,NULL,0);
1454 if(len2!=counter){
1455 asn1_delete_structure(structure);
1456 return ASN1_DER_ERROR;
1459 if(p==nodeFound) state=EXIT;
1461 else{ /* move==DOWN || move==RIGHT */
1462 if(state==OTHER_BRANCH){
1463 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1464 if(len3 < 0) return ASN1_DER_ERROR;
1465 counter+=len2+len3;
1466 move=RIGHT;
1468 else{ /* state==FOUND or state==SAME_BRANCH */
1469 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1470 if(len3 < 0) return ASN1_DER_ERROR;
1471 counter+=len2;
1472 if(len3){
1473 _asn1_ltostr(counter+len3,temp);
1474 tlen = strlen(temp);
1476 if (tlen > 0)
1477 _asn1_set_value(p,temp,tlen+1);
1478 p2=p->down;
1479 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1480 if(p2->right==NULL) _asn1_append_sequence_set(p);
1481 p=p2;
1482 state=FOUND;
1487 break;
1488 case TYPE_ANY:
1489 if(asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
1490 return ASN1_DER_ERROR;
1491 if (counter+len2 > len)
1492 return ASN1_DER_ERROR;
1494 len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
1495 if(len4 < -1) return ASN1_DER_ERROR;
1497 if(len4 != -1){
1498 len2+=len4;
1499 if(state==FOUND){
1500 asn1_length_der(len2+len3,NULL,&len4);
1501 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
1502 if (temp2==NULL){
1503 asn1_delete_structure(structure);
1504 return ASN1_MEM_ALLOC_ERROR;
1507 asn1_octet_der(der+counter,len2+len3,temp2,&len4);
1508 _asn1_set_value(p,temp2,len4);
1509 _asn1_afree(temp2);
1511 if(p==nodeFound) state=EXIT;
1513 counter+=len2+len3;
1515 else{ /* indefinite length */
1516 /* Check indefinite lenth method in an EXPLICIT TAG */
1517 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1518 indefinite=1;
1519 else
1520 indefinite=0;
1522 len2=len-counter;
1523 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1524 if(ris != ASN1_SUCCESS){
1525 asn1_delete_structure(structure);
1526 return ris;
1529 if(state==FOUND){
1530 asn1_length_der(len2,NULL,&len4);
1531 temp2=(unsigned char *)_asn1_alloca(len2+len4);
1532 if (temp2==NULL){
1533 asn1_delete_structure(structure);
1534 return ASN1_MEM_ALLOC_ERROR;
1537 asn1_octet_der(der+counter,len2,temp2,&len4);
1538 _asn1_set_value(p,temp2,len4);
1539 _asn1_afree(temp2);
1541 if(p==nodeFound) state=EXIT;
1544 counter+=len2;
1546 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1547 an indefinite length method. */
1548 if(indefinite){
1549 if(!der[counter] && !der[counter+1]){
1550 counter+=2;
1552 else{
1553 asn1_delete_structure(structure);
1554 return ASN1_DER_ERROR;
1558 move=RIGHT;
1559 break;
1561 default:
1562 move=(move==UP)?RIGHT:DOWN;
1563 break;
1567 if((p==node && move!=DOWN) || (state==EXIT)) break;
1569 if(move==DOWN){
1570 if(p->down){
1571 p=p->down;
1573 if(state != FOUND){
1574 nameLen-=strlen(p->name)+1;
1575 if(nameLen>0){
1576 if(currentName[0]) strcat(currentName,".");
1577 strcat(currentName,p->name);
1579 else{
1580 asn1_delete_structure(structure);
1581 return ASN1_MEM_ERROR;
1583 if(!(strcmp(currentName,elementName))){
1584 state=FOUND;
1585 nodeFound=p;
1587 else if(!memcmp(currentName,elementName,strlen(currentName)))
1588 state=SAME_BRANCH;
1589 else
1590 state=OTHER_BRANCH;
1593 else move=RIGHT;
1596 if((move==RIGHT) && !(p->type&CONST_SET)){
1597 if(p->right){
1598 p=p->right;
1600 if(state != FOUND){
1601 dot_p=char_p=currentName;
1602 while((char_p=strchr(char_p,'.'))){
1603 dot_p=char_p++;
1604 dot_p++;
1607 nameLen+=strlen(currentName)-(dot_p-currentName);
1608 *dot_p=0;
1610 nameLen-=strlen(p->name);
1611 if(nameLen>0) strcat(currentName,p->name);
1612 else{
1613 asn1_delete_structure(structure);
1614 return ASN1_MEM_ERROR;
1617 if(!(strcmp(currentName,elementName))){
1618 state=FOUND;
1619 nodeFound=p;
1621 else if(!memcmp(currentName,elementName,strlen(currentName)))
1622 state=SAME_BRANCH;
1623 else
1624 state=OTHER_BRANCH;
1627 else move=UP;
1630 if(move==UP){
1631 p=_asn1_find_up(p);
1633 if(state != FOUND){
1634 dot_p=char_p=currentName;
1635 while((char_p=strchr(char_p,'.'))){
1636 dot_p=char_p++;
1637 dot_p++;
1640 nameLen+=strlen(currentName)-(dot_p-currentName);
1641 *dot_p=0;
1643 if(!(strcmp(currentName,elementName))){
1644 state=FOUND;
1645 nodeFound=p;
1647 else if(!memcmp(currentName,elementName,strlen(currentName)))
1648 state=SAME_BRANCH;
1649 else
1650 state=OTHER_BRANCH;
1655 _asn1_delete_not_used(*structure);
1657 if(counter > len){
1658 asn1_delete_structure(structure);
1659 return ASN1_DER_ERROR;
1662 return ASN1_SUCCESS;
1668 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1669 * @element: pointer to an ASN1 element
1670 * @ider: vector that contains the DER encoding.
1671 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
1672 * @name_element: an element of NAME structure.
1673 * @start: the position of the first byte of NAME_ELEMENT decoding
1674 * (@ider[*start])
1675 * @end: the position of the last byte of NAME_ELEMENT decoding
1676 * (@ider[*end])
1678 * Find the start and end point of an element in a DER encoding
1679 * string. I mean that if you have a der encoding and you have
1680 * already used the function "asn1_der_decoding" to fill a structure,
1681 * it may happen that you want to find the piece of string concerning
1682 * an element of the structure.
1684 * Example: the sequence "tbsCertificate" inside an X509 certificate.
1686 * Returns:
1688 * ASN1_SUCCESS: DER encoding OK.
1690 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or
1691 * NAME_ELEMENT is not a valid element.
1693 * ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match
1694 * the structure ELEMENT.
1697 asn1_retCode
1698 asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
1699 const char *name_element,int *start, int *end)
1701 node_asn *node,*node_to_find,*p,*p2,*p3;
1702 int counter,len2,len3,len4,move,ris;
1703 unsigned char class;
1704 unsigned long tag;
1705 int indefinite;
1706 const unsigned char* der = ider;
1708 node=element;
1710 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1712 node_to_find=_asn1_find_node(node,name_element);
1714 if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
1716 if(node_to_find==node){
1717 *start=0;
1718 *end=len-1;
1719 return ASN1_SUCCESS;
1722 if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
1724 counter=0;
1725 move=DOWN;
1726 p=node;
1727 while(1){
1728 ris=ASN1_SUCCESS;
1730 if(move!=UP){
1731 if(p->type&CONST_SET){
1732 p2=_asn1_find_up(p);
1733 len2=strtol(p2->value,NULL,10);
1734 if(len2==-1){
1735 if(!der[counter] && !der[counter+1]){
1736 p=p2;
1737 move=UP;
1738 counter+=2;
1739 continue;
1742 else if(counter==len2){
1743 p=p2;
1744 move=UP;
1745 continue;
1747 else if(counter>len2) return ASN1_DER_ERROR;
1748 p2=p2->down;
1749 while(p2){
1750 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
1751 if(type_field(p2->type)!=TYPE_CHOICE)
1752 ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
1753 else{
1754 p3=p2->down;
1755 ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
1757 if(ris==ASN1_SUCCESS){
1758 p2->type&=~CONST_NOT_USED;
1759 p=p2;
1760 break;
1763 p2=p2->right;
1765 if(p2==NULL) return ASN1_DER_ERROR;
1768 if(p==node_to_find) *start=counter;
1770 if(type_field(p->type)==TYPE_CHOICE){
1771 p=p->down;
1772 ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
1773 if(p==node_to_find) *start=counter;
1776 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
1777 if(ris!=ASN1_SUCCESS){
1778 if(p->type&CONST_OPTION){
1779 p->type|=CONST_NOT_USED;
1780 move=RIGHT;
1782 else if(p->type&CONST_DEFAULT) {
1783 move=RIGHT;
1785 else {
1786 return ASN1_TAG_ERROR;
1789 else counter+=len2;
1792 if(ris==ASN1_SUCCESS){
1793 switch(type_field(p->type)){
1794 case TYPE_NULL:
1795 if(der[counter]) return ASN1_DER_ERROR;
1796 counter++;
1797 move=RIGHT;
1798 break;
1799 case TYPE_BOOLEAN:
1800 if(der[counter++]!=1) return ASN1_DER_ERROR;
1801 counter++;
1802 move=RIGHT;
1803 break;
1804 case TYPE_INTEGER: case TYPE_ENUMERATED:
1805 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1806 if(len2 < 0) return ASN1_DER_ERROR;
1807 counter+=len3+len2;
1808 move=RIGHT;
1809 break;
1810 case TYPE_OBJECT_ID:
1811 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1812 if(len2 < 0) return ASN1_DER_ERROR;
1813 counter+=len2+len3;
1814 move=RIGHT;
1815 break;
1816 case TYPE_TIME:
1817 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1818 if(len2 < 0) return ASN1_DER_ERROR;
1819 counter+=len2+len3;
1820 move=RIGHT;
1821 break;
1822 case TYPE_OCTET_STRING:
1823 len3=len-counter;
1824 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1825 if(ris != ASN1_SUCCESS) return ris;
1826 counter+=len3;
1827 move=RIGHT;
1828 break;
1829 case TYPE_GENERALSTRING:
1830 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1831 if(len2 < 0) return ASN1_DER_ERROR;
1832 counter+=len3+len2;
1833 move=RIGHT;
1834 break;
1835 case TYPE_BIT_STRING:
1836 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1837 if(len2 < 0) return ASN1_DER_ERROR;
1838 counter+=len3+len2;
1839 move=RIGHT;
1840 break;
1841 case TYPE_SEQUENCE: case TYPE_SET:
1842 if(move!=UP){
1843 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1844 if(len3 < -1) return ASN1_DER_ERROR;
1845 counter+=len2;
1846 if(len3==0) move=RIGHT;
1847 else move=DOWN;
1849 else{
1850 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1851 counter+=2;
1852 move=RIGHT;
1854 break;
1855 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1856 if(move!=UP){
1857 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1858 if(len3 < -1) return ASN1_DER_ERROR;
1859 counter+=len2;
1860 if((len3==-1) && !der[counter] && !der[counter+1])
1861 counter+=2;
1862 else if(len3){
1863 p2=p->down;
1864 while((type_field(p2->type)==TYPE_TAG) ||
1865 (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1866 p=p2;
1869 else{
1870 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1871 counter+=2;
1873 move=RIGHT;
1874 break;
1875 case TYPE_ANY:
1876 if (asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
1877 return ASN1_DER_ERROR;
1878 if (counter+len2 > len)
1879 return ASN1_DER_ERROR;
1881 len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
1882 if(len4 < -1) return ASN1_DER_ERROR;
1884 if(len4 != -1){
1885 counter+=len2+len4+len3;
1887 else{ /* indefinite length */
1888 /* Check indefinite lenth method in an EXPLICIT TAG */
1889 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1890 indefinite=1;
1891 else
1892 indefinite=0;
1894 len2=len-counter;
1895 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1896 if(ris != ASN1_SUCCESS)
1897 return ris;
1898 counter+=len2;
1900 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1901 an indefinite length method. */
1902 if(indefinite){
1903 if(!der[counter] && !der[counter+1])
1904 counter+=2;
1905 else
1906 return ASN1_DER_ERROR;
1909 move=RIGHT;
1910 break;
1911 default:
1912 move=(move==UP)?RIGHT:DOWN;
1913 break;
1917 if((p==node_to_find) && (move==RIGHT)){
1918 *end=counter-1;
1919 return ASN1_SUCCESS;
1922 if(p==node && move!=DOWN) break;
1924 if(move==DOWN){
1925 if(p->down) p=p->down;
1926 else move=RIGHT;
1928 if((move==RIGHT) && !(p->type&CONST_SET)){
1929 if(p->right) p=p->right;
1930 else move=UP;
1932 if(move==UP) p=_asn1_find_up(p);
1935 return ASN1_ELEMENT_NOT_FOUND;
1940 * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure.
1941 * @definitions: ASN1 definitions
1942 * @element: pointer to an ASN1 structure
1944 * Expands every "ANY DEFINED BY" element of a structure created from
1945 * a DER decoding process (asn1_der_decoding function). The element ANY
1946 * must be defined by an OBJECT IDENTIFIER. The type used to expand
1947 * the element ANY is the first one following the definition of
1948 * the actual value of the OBJECT IDENTIFIER.
1951 * Returns:
1953 * ASN1_SUCCESS: Substitution OK.
1955 * ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be
1956 * expanded due to a problem in OBJECT_ID -> TYPE association.
1958 * other errors: Result of der decoding process.
1961 asn1_retCode
1962 asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
1964 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1965 asn1_retCode retCode=ASN1_SUCCESS,result;
1966 int len,len2,len3;
1967 ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
1968 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1970 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1971 return ASN1_ELEMENT_NOT_FOUND;
1973 strcpy(definitionsName,definitions->name);
1974 strcat(definitionsName,".");
1976 p=*element;
1977 while(p){
1979 switch(type_field(p->type)){
1980 case TYPE_ANY:
1981 if((p->type&CONST_DEFINED_BY) && (p->value)){
1982 /* search the "DEF_BY" element */
1983 p2=p->down;
1984 while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
1985 p2=p2->right;
1987 if(!p2){
1988 retCode=ASN1_ERROR_TYPE_ANY;
1989 break;
1992 p3=_asn1_find_up(p);
1994 if(!p3){
1995 retCode=ASN1_ERROR_TYPE_ANY;
1996 break;
1999 p3=p3->down;
2000 while(p3){
2001 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
2002 p3=p3->right;
2005 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
2006 (p3->value==NULL)){
2008 p3=_asn1_find_up(p);
2009 p3=_asn1_find_up(p3);
2011 if(!p3){
2012 retCode=ASN1_ERROR_TYPE_ANY;
2013 break;
2016 p3=p3->down;
2018 while(p3){
2019 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
2020 p3=p3->right;
2023 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
2024 (p3->value==NULL)){
2025 retCode=ASN1_ERROR_TYPE_ANY;
2026 break;
2030 /* search the OBJECT_ID into definitions */
2031 p2=definitions->down;
2032 while(p2){
2033 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
2034 (p2->type & CONST_ASSIGN)){
2035 strcpy(name,definitionsName);
2036 strcat(name,p2->name);
2038 len=MAX_NAME_SIZE;
2039 result=asn1_read_value(definitions,name,value,&len);
2041 if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
2042 p2=p2->right; /* pointer to the structure to
2043 use for expansion */
2044 while((p2) && (p2->type & CONST_ASSIGN))
2045 p2=p2->right;
2047 if(p2){
2048 strcpy(name,definitionsName);
2049 strcat(name,p2->name);
2051 result=asn1_create_element(definitions,name,&aux);
2052 if(result == ASN1_SUCCESS){
2053 _asn1_set_name(aux,p->name);
2054 len2=asn1_get_length_der(p->value,p->value_len,&len3);
2055 if(len2 < 0) return ASN1_DER_ERROR;
2057 result=asn1_der_decoding(&aux,p->value+len3,len2,
2058 errorDescription);
2059 if(result == ASN1_SUCCESS){
2061 _asn1_set_right(aux,p->right);
2062 _asn1_set_right(p,aux);
2064 result=asn1_delete_structure(&p);
2065 if(result == ASN1_SUCCESS){
2066 p=aux;
2067 aux=ASN1_TYPE_EMPTY;
2068 break;
2070 else{ /* error with asn1_delete_structure */
2071 asn1_delete_structure(&aux);
2072 retCode=result;
2073 break;
2076 else{/* error with asn1_der_decoding */
2077 retCode=result;
2078 break;
2081 else{/* error with asn1_create_element */
2082 retCode=result;
2083 break;
2086 else{/* error with the pointer to the structure to exapand */
2087 retCode=ASN1_ERROR_TYPE_ANY;
2088 break;
2092 p2=p2->right;
2093 } /* end while */
2095 if(!p2){
2096 retCode=ASN1_ERROR_TYPE_ANY;
2097 break;
2101 break;
2102 default:
2103 break;
2107 if(p->down){
2108 p=p->down;
2110 else if(p==*element){
2111 p=NULL;
2112 break;
2114 else if(p->right) p=p->right;
2115 else{
2116 while(1){
2117 p=_asn1_find_up(p);
2118 if(p==*element){
2119 p=NULL;
2120 break;
2122 if(p->right){
2123 p=p->right;
2124 break;
2130 return retCode;
2136 * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure.
2137 * @definitions: ASN1 definitions
2138 * @element: pointer to an ASN1 structure
2139 * @octetName: name of the OCTECT STRING field to expand.
2140 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2141 * the type for expansion.
2143 * Expands an "OCTET STRING" element of a structure created from a
2144 * DER decoding process (asn1_der_decoding function). The type used
2145 * for expansion is the first one following the definition of the
2146 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2148 * Returns:
2150 * ASN1_SUCCESS: Substitution OK.
2152 * ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct.
2154 * ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use
2155 * for expansion.
2157 * other errors: result of der decoding process.
2159 asn1_retCode
2160 asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
2161 const char *octetName,const char *objectName)
2163 char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
2164 asn1_retCode retCode=ASN1_SUCCESS,result;
2165 int len,len2,len3;
2166 ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
2167 ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
2168 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
2170 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
2171 return ASN1_ELEMENT_NOT_FOUND;
2173 octetNode=_asn1_find_node(*element,octetName);
2174 if(octetNode==ASN1_TYPE_EMPTY)
2175 return ASN1_ELEMENT_NOT_FOUND;
2176 if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
2177 return ASN1_ELEMENT_NOT_FOUND;
2178 if(octetNode->value==NULL)
2179 return ASN1_VALUE_NOT_FOUND;
2181 objectNode=_asn1_find_node(*element,objectName);
2182 if(objectNode==ASN1_TYPE_EMPTY)
2183 return ASN1_ELEMENT_NOT_FOUND;
2185 if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
2186 return ASN1_ELEMENT_NOT_FOUND;
2188 if(objectNode->value==NULL)
2189 return ASN1_VALUE_NOT_FOUND;
2192 /* search the OBJECT_ID into definitions */
2193 p2=definitions->down;
2194 while(p2){
2195 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
2196 (p2->type & CONST_ASSIGN)){
2197 strcpy(name,definitions->name);
2198 strcat(name,".");
2199 strcat(name,p2->name);
2201 len = sizeof(value);
2202 result=asn1_read_value(definitions,name,value,&len);
2204 if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
2206 p2=p2->right; /* pointer to the structure to
2207 use for expansion */
2208 while((p2) && (p2->type & CONST_ASSIGN))
2209 p2=p2->right;
2211 if(p2){
2212 strcpy(name,definitions->name);
2213 strcat(name,".");
2214 strcat(name,p2->name);
2216 result=asn1_create_element(definitions,name,&aux);
2217 if(result == ASN1_SUCCESS){
2218 _asn1_set_name(aux,octetNode->name);
2219 len2=asn1_get_length_der(octetNode->value,octetNode->value_len,&len3);
2220 if(len2 < 0) return ASN1_DER_ERROR;
2222 result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
2223 errorDescription);
2224 if(result == ASN1_SUCCESS){
2226 _asn1_set_right(aux,octetNode->right);
2227 _asn1_set_right(octetNode,aux);
2229 result=asn1_delete_structure(&octetNode);
2230 if(result == ASN1_SUCCESS){
2231 aux=ASN1_TYPE_EMPTY;
2232 break;
2234 else{ /* error with asn1_delete_structure */
2235 asn1_delete_structure(&aux);
2236 retCode=result;
2237 break;
2240 else{/* error with asn1_der_decoding */
2241 retCode=result;
2242 break;
2245 else{/* error with asn1_create_element */
2246 retCode=result;
2247 break;
2250 else{/* error with the pointer to the structure to exapand */
2251 retCode=ASN1_VALUE_NOT_VALID;
2252 break;
2257 p2=p2->right;
2261 if(!p2) retCode=ASN1_VALUE_NOT_VALID;
2263 return retCode;