Doc fix for asn1_get_octet_der.
[libtasn1.git] / lib / decoding.c
blob0bbcda05ee623230ce6169c74ca4b1de7c3c9196
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,"'");
50 signed long
51 asn1_get_length_der(const unsigned char *der, int der_len, int *len)
53 unsigned long ans;
54 int k,punt;
56 *len = 0;
57 if (der_len <= 0) return 0;
59 if(!(der[0]&128)){
60 /* short form */
61 *len=1;
62 return der[0];
64 else{
65 /* Long form */
66 k=der[0]&0x7F;
67 punt=1;
68 if(k){ /* definite length method */
69 ans=0;
70 while(punt<=k && punt < der_len) {
71 unsigned long last = ans;
72 ans=ans*256+der[punt++];
73 if (ans < last)
74 /* we wrapped around, no bignum support... */
75 return -2;
78 else{ /* indefinite length method */
79 ans=-1;
82 *len=punt;
83 return ans;
90 /**
91 * asn1_get_tag_der:
92 * @der: DER data to decode.
93 * @der_len: Length of DER data to decode.
94 * @class: Output variable containing decoded class.
95 * @len: Output variable containing the length of the DER TAG data.
96 * @tag: Output variable containing the decoded tag.
98 * Decode the class and TAG from DER code.
100 * Return value: Returns ASN1_SUCCESS on success, or an error.
103 asn1_get_tag_der(const unsigned char *der, int der_len,
104 unsigned char *class,int *len, unsigned long *tag)
106 int punt,ris;
108 if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR;
110 *class=der[0]&0xE0;
111 if((der[0]&0x1F)!=0x1F){
112 /* short form */
113 *len=1;
114 ris=der[0]&0x1F;
116 else{
117 /* Long form */
118 punt=1;
119 ris=0;
120 while(punt <= der_len && der[punt]&128)
122 int last = ris;
123 ris=ris*128+(der[punt++]&0x7F);
124 if (ris < last)
125 /* wrapper around, and no bignums... */
126 return ASN1_DER_ERROR;
128 if (punt >= der_len)
129 return ASN1_DER_ERROR;
131 int last = ris;
132 ris=ris*128+(der[punt++]&0x7F);
133 if (ris < last)
134 /* wrapper around, and no bignums... */
135 return ASN1_DER_ERROR;
137 *len=punt;
139 if (tag) *tag = ris;
140 return ASN1_SUCCESS;
147 * asn1_get_octet_der:
148 * @der: DER data to decode containing the OCTET SEQUENCE.
149 * @der_len: Length of DER data to decode.
150 * @ret_len: Output variable containing the length of the DER data.
151 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
152 * @str_size: Length of pre-allocated output buffer.
153 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
155 * Extract an OCTET SEQUENCE from DER data.
157 * Return value: Returns ASN1_SUCCESS on success, or an error.
160 asn1_get_octet_der(const unsigned char *der, int der_len,
161 int *ret_len,unsigned char *str, int str_size, int *str_len)
163 int len_len;
165 if (der_len <= 0) return ASN1_GENERIC_ERROR;
167 /* if(str==NULL) return ASN1_SUCCESS; */
168 *str_len=asn1_get_length_der(der, der_len, &len_len);
170 if (*str_len < 0)
171 return ASN1_DER_ERROR;
173 *ret_len=*str_len+len_len;
174 if ( str_size >= *str_len)
175 memcpy(str,der+len_len,*str_len);
176 else {
177 return ASN1_MEM_ERROR;
180 return ASN1_SUCCESS;
185 /* Returns ASN1_SUCCESS on success or an error code on error.
188 _asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size)
190 int len_len,str_len;
192 if(der_len <=0 || str==NULL) return ASN1_DER_ERROR;
193 str_len=asn1_get_length_der(der, der_len, &len_len);
194 if (str_len < 0 || str_size < str_len)
195 return ASN1_DER_ERROR;
196 memcpy(str,der+len_len,str_len);
197 str[str_len]=0;
198 *ret_len=str_len+len_len;
200 return ASN1_SUCCESS;
205 void
206 _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size)
208 int len_len,len,k;
209 char temp[20];
210 unsigned long val,val1;
212 *ret_len = 0;
213 if (str && str_size > 0) str[0] = 0; /* no oid */
215 if(str==NULL || der_len <= 0) return;
216 len=asn1_get_length_der(der,der_len, &len_len);
218 if (len < 0 || len > der_len || len_len > der_len) return;
220 val1=der[len_len]/40;
221 val=der[len_len]-val1*40;
223 _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
224 _asn1_str_cat(str, str_size, ".");
225 _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
227 val=0;
228 for(k=1;k<len;k++){
229 val=val<<7;
230 val|=der[len_len+k]&0x7F;
231 if(!(der[len_len+k]&0x80)){
232 _asn1_str_cat(str, str_size,".");
233 _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
234 val=0;
237 *ret_len=len+len_len;
244 asn1_get_bit_der(const unsigned char *der, int der_len,
245 int *ret_len,unsigned char *str, int str_size, int *bit_len)
247 int len_len,len_byte;
249 if (der_len <=0) return ASN1_GENERIC_ERROR;
250 len_byte=asn1_get_length_der(der,der_len,&len_len)-1;
251 if (len_byte < 0)
252 return ASN1_DER_ERROR;
254 *ret_len=len_byte+len_len+1;
255 *bit_len=len_byte*8-der[len_len];
257 if (str_size >= len_byte)
258 memcpy(str,der+len_len+1,len_byte);
259 else {
260 return ASN1_MEM_ERROR;
263 return ASN1_SUCCESS;
270 _asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len)
272 node_asn *p;
273 int counter,len2,len3,is_tag_implicit;
274 unsigned long tag,tag_implicit=0;
275 unsigned char class,class2,class_implicit=0;
277 if (der_len <= 0) return ASN1_GENERIC_ERROR;
279 counter=is_tag_implicit=0;
281 if(node->type&CONST_TAG){
282 p=node->down;
283 while(p){
284 if(type_field(p->type)==TYPE_TAG){
285 if(p->type&CONST_APPLICATION) class2=APPLICATION;
286 else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
287 else if(p->type&CONST_PRIVATE) class2=PRIVATE;
288 else class2=CONTEXT_SPECIFIC;
290 if(p->type&CONST_EXPLICIT){
291 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
292 return ASN1_DER_ERROR;
293 if (counter+len2 > der_len)
294 return ASN1_DER_ERROR;
295 counter+=len2;
296 len3=asn1_get_length_der(der+counter,der_len-counter, &len2);
297 if (len3 < 0)
298 return ASN1_DER_ERROR;
299 counter+=len2;
300 if(!is_tag_implicit){
301 if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
302 return ASN1_TAG_ERROR;
304 else{ /* TAG_IMPLICIT */
305 if((class!=class_implicit) || (tag!=tag_implicit))
306 return ASN1_TAG_ERROR;
309 is_tag_implicit=0;
311 else{ /* TAG_IMPLICIT */
312 if(!is_tag_implicit){
313 if((type_field(node->type)==TYPE_SEQUENCE) ||
314 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
315 (type_field(node->type)==TYPE_SET) ||
316 (type_field(node->type)==TYPE_SET_OF)) class2|=STRUCTURED;
317 class_implicit=class2;
318 tag_implicit=strtoul(p->value,NULL,10);
319 is_tag_implicit=1;
323 p=p->right;
327 if(is_tag_implicit){
328 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
329 return ASN1_DER_ERROR;
330 if (counter+len2 > der_len)
331 return ASN1_DER_ERROR;
333 if((class!=class_implicit) || (tag!=tag_implicit)){
334 if(type_field(node->type)==TYPE_OCTET_STRING){
335 class_implicit |= STRUCTURED;
336 if((class!=class_implicit) || (tag!=tag_implicit))
337 return ASN1_TAG_ERROR;
339 else
340 return ASN1_TAG_ERROR;
343 else{
344 if(type_field(node->type)==TYPE_TAG){
345 counter=0;
346 *ret_len=counter;
347 return ASN1_SUCCESS;
350 if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
351 return ASN1_DER_ERROR;
352 if (counter+len2 > der_len)
353 return ASN1_DER_ERROR;
355 switch(type_field(node->type)){
356 case TYPE_NULL:
357 if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
358 break;
359 case TYPE_BOOLEAN:
360 if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
361 break;
362 case TYPE_INTEGER:
363 if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
364 break;
365 case TYPE_ENUMERATED:
366 if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
367 break;
368 case TYPE_OBJECT_ID:
369 if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
370 break;
371 case TYPE_TIME:
372 if(node->type&CONST_UTC){
373 if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
375 else{
376 if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime))
377 return ASN1_DER_ERROR;
379 break;
380 case TYPE_OCTET_STRING:
381 if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
382 || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
383 break;
384 case TYPE_GENERALSTRING:
385 if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
386 break;
387 case TYPE_BIT_STRING:
388 if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
389 break;
390 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
391 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE))
392 return ASN1_DER_ERROR;
393 break;
394 case TYPE_SET: case TYPE_SET_OF:
395 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET))
396 return ASN1_DER_ERROR;
397 break;
398 case TYPE_ANY:
399 counter-=len2;
400 break;
401 default:
402 return ASN1_DER_ERROR;
403 break;
407 counter+=len2;
408 *ret_len=counter;
409 return ASN1_SUCCESS;
413 int
414 _asn1_delete_not_used(node_asn *node)
416 node_asn *p,*p2;
418 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
420 p=node;
421 while(p){
422 if(p->type&CONST_NOT_USED){
423 p2=NULL;
424 if(p!=node){
425 p2=_asn1_find_left(p);
426 if(!p2) p2=_asn1_find_up(p);
428 asn1_delete_structure(&p);
429 p=p2;
432 if(!p) break; /* reach node */
434 if(p->down){
435 p=p->down;
437 else{
438 if(p==node) p=NULL;
439 else if(p->right) p=p->right;
440 else{
441 while(1){
442 p=_asn1_find_up(p);
443 if(p==node){
444 p=NULL;
445 break;
447 if(p->right){
448 p=p->right;
449 break;
455 return ASN1_SUCCESS;
459 asn1_retCode
460 _asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len)
462 int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
463 char *temp,*temp2;
465 counter=0;
467 if(*(der-1) & STRUCTURED){
468 tot_len=0;
469 indefinite=asn1_get_length_der(der, *len, &len3);
470 if (indefinite < -1)
471 return ASN1_DER_ERROR;
473 counter+=len3;
474 if(indefinite>=0) indefinite+=len3;
476 while(1){
477 if(counter>(*len)) return ASN1_DER_ERROR;
479 if(indefinite==-1){
480 if((der[counter]==0) && (der[counter+1]==0)){
481 counter+=2;
482 break;
485 else if(counter>=indefinite) break;
487 if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
489 counter++;
491 len2=asn1_get_length_der(der+counter,*len-counter, &len3);
492 if(len2 <= 0) return ASN1_DER_ERROR;
494 counter+=len3+len2;
495 tot_len+=len2;
498 /* copy */
499 if(node){
500 asn1_length_der(tot_len,NULL,&len2);
501 temp=(unsigned char *)_asn1_alloca(len2+tot_len);
502 if (temp==NULL){
503 return ASN1_MEM_ALLOC_ERROR;
506 asn1_length_der(tot_len,temp,&len2);
507 tot_len+=len2;
508 temp2=temp+len2;
509 len2=asn1_get_length_der(der,*len,&len3);
510 if(len2 < -1) return ASN1_DER_ERROR;
511 counter2=len3+1;
513 if(indefinite==-1) counter_end=counter-2;
514 else counter_end=counter;
516 while(counter2<counter_end){
517 len2=asn1_get_length_der(der+counter2, *len-counter, &len3);
518 if(len2 < -1) return ASN1_DER_ERROR;
520 /* FIXME: to be checked. Is this ok? Has the
521 * size been checked before?
523 memcpy(temp2,der+counter2+len3,len2);
524 temp2+=len2;
525 counter2+=len2+len3+1;
528 _asn1_set_value(node,temp,tot_len);
529 _asn1_afree(temp);
532 else{ /* NOT STRUCTURED */
533 len2=asn1_get_length_der(der, *len, &len3);
534 if(len2 < 0) return ASN1_DER_ERROR;
535 if (len3+len2 > *len) return ASN1_DER_ERROR;
536 if(node)
537 _asn1_set_value(node,der,len3+len2);
538 counter=len3+len2;
541 *len=counter;
542 return ASN1_SUCCESS;
547 asn1_retCode
548 _asn1_get_indefinite_length_string(const unsigned char* der, int* len)
550 int len2,len3,counter,indefinite;
551 unsigned long tag;
552 unsigned char class;
554 counter=indefinite=0;
556 while(1){
557 if((*len)<counter) return ASN1_DER_ERROR;
559 if((der[counter]==0) && (der[counter+1]==0)){
560 counter+=2;
561 indefinite--;
562 if(indefinite<=0) break;
563 else continue;
566 if(asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
567 return ASN1_DER_ERROR;
568 if (counter+len2 > *len)
569 return ASN1_DER_ERROR;
570 counter+=len2;
571 len2=asn1_get_length_der(der+counter, *len-counter,&len3);
572 if(len2 < -1) return ASN1_DER_ERROR;
573 if(len2 == -1){
574 indefinite++;
575 counter+=1;
577 else{
578 counter+=len2+len3;
582 *len=counter;
583 return ASN1_SUCCESS;
589 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
590 * @element: pointer to an ASN1 structure.
591 * @ider: vector that contains the DER encoding.
592 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
593 * @errorDescription: null-terminated string contains details when an
594 * error occurred.
596 * Fill the structure *ELEMENT with values of a DER encoding
597 * string. The sructure must just be created with function
598 * 'create_stucture'. If an error occurs during the decoding
599 * procedure, the *ELEMENT is deleted and set equal to
600 * %ASN1_TYPE_EMPTY.
602 * Returns:
604 * ASN1_SUCCESS: DER encoding OK.
606 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY.
608 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
609 * the structure NAME. *ELEMENT deleted.
612 asn1_retCode
613 asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
614 char *errorDescription)
616 node_asn *node,*p,*p2,*p3;
617 char temp[128];
618 int counter,len2,len3,len4,move,ris,tlen;
619 unsigned char class,*temp2;
620 unsigned long tag;
621 int indefinite, result;
622 const unsigned char* der = ider;
624 node=*element;
626 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
628 if(node->type&CONST_OPTION){
629 asn1_delete_structure(element);
630 return ASN1_GENERIC_ERROR;
633 counter=0;
634 move=DOWN;
635 p=node;
636 while(1){
637 ris=ASN1_SUCCESS;
638 if(move!=UP){
639 if(p->type&CONST_SET){
640 p2=_asn1_find_up(p);
641 len2=strtol(p2->value,NULL,10);
642 if(len2==-1){
643 if(!der[counter] && !der[counter+1]){
644 p=p2;
645 move=UP;
646 counter+=2;
647 continue;
650 else if(counter==len2){
651 p=p2;
652 move=UP;
653 continue;
655 else if(counter>len2){
656 asn1_delete_structure(element);
657 return ASN1_DER_ERROR;
659 p2=p2->down;
660 while(p2){
661 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
662 if(type_field(p2->type)!=TYPE_CHOICE)
663 ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2);
664 else{
665 p3=p2->down;
666 while(p3){
667 ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2);
668 if(ris==ASN1_SUCCESS) break;
669 p3=p3->right;
672 if(ris==ASN1_SUCCESS){
673 p2->type&=~CONST_NOT_USED;
674 p=p2;
675 break;
678 p2=p2->right;
680 if(p2==NULL){
681 asn1_delete_structure(element);
682 return ASN1_DER_ERROR;
686 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
687 p2=_asn1_find_up(p);
688 len2=strtol(p2->value,NULL,10);
689 if(counter==len2){
690 if(p->right){
691 p2=p->right;
692 move=RIGHT;
694 else move=UP;
696 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
698 p=p2;
699 continue;
703 if(type_field(p->type)==TYPE_CHOICE){
704 while(p->down){
705 if(counter<len)
706 ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
707 else
708 ris=ASN1_DER_ERROR;
709 if(ris==ASN1_SUCCESS){
710 while(p->down->right){
711 p2=p->down->right;
712 asn1_delete_structure(&p2);
714 break;
716 else if(ris==ASN1_ERROR_TYPE_ANY){
717 asn1_delete_structure(element);
718 return ASN1_ERROR_TYPE_ANY;
720 else{
721 p2=p->down;
722 asn1_delete_structure(&p2);
726 if(p->down==NULL){
727 if(!(p->type&CONST_OPTION)){
728 asn1_delete_structure(element);
729 return ASN1_DER_ERROR;
732 else
733 p=p->down;
736 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
737 p2=_asn1_find_up(p);
738 len2=strtol(p2->value,NULL,10);
739 if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
742 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
743 if(ris!=ASN1_SUCCESS){
744 if(p->type&CONST_OPTION){
745 p->type|=CONST_NOT_USED;
746 move=RIGHT;
748 else if(p->type&CONST_DEFAULT) {
749 _asn1_set_value(p,NULL,0);
750 move=RIGHT;
752 else {
753 if (errorDescription!=NULL)
754 _asn1_error_description_tag_error(p,errorDescription);
756 asn1_delete_structure(element);
757 return ASN1_TAG_ERROR;
760 else counter+=len2;
763 if(ris==ASN1_SUCCESS){
764 switch(type_field(p->type)){
765 case TYPE_NULL:
766 if(der[counter]){
767 asn1_delete_structure(element);
768 return ASN1_DER_ERROR;
770 counter++;
771 move=RIGHT;
772 break;
773 case TYPE_BOOLEAN:
774 if(der[counter++]!=1){
775 asn1_delete_structure(element);
776 return ASN1_DER_ERROR;
778 if(der[counter++]==0) _asn1_set_value(p,"F",1);
779 else _asn1_set_value(p,"T",1);
780 move=RIGHT;
781 break;
782 case TYPE_INTEGER: case TYPE_ENUMERATED:
783 len2=asn1_get_length_der(der+counter,len-counter, &len3);
784 if(len2 < 0) return ASN1_DER_ERROR;
785 if (len2+len3 > len-counter) return ASN1_DER_ERROR;
786 _asn1_set_value(p,der+counter,len3+len2);
787 counter+=len3+len2;
788 move=RIGHT;
789 break;
790 case TYPE_OBJECT_ID:
791 _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
792 tlen = strlen(temp);
793 if( tlen > 0)
794 _asn1_set_value(p,temp,tlen+1);
795 counter+=len2;
796 move=RIGHT;
797 break;
798 case TYPE_TIME:
799 result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
800 if (result != ASN1_SUCCESS) {
801 asn1_delete_structure(element);
802 return result;
804 tlen = strlen(temp);
805 if (tlen > 0)
806 _asn1_set_value(p,temp,tlen+1);
807 counter+=len2;
808 move=RIGHT;
809 break;
810 case TYPE_OCTET_STRING:
811 len3=len-counter;
812 ris=_asn1_get_octet_string(der+counter,p,&len3);
813 if(ris != ASN1_SUCCESS) return ris;
814 counter+=len3;
815 move=RIGHT;
816 break;
817 case TYPE_GENERALSTRING:
818 len2=asn1_get_length_der(der+counter,len-counter,&len3);
819 if(len2 < 0) return ASN1_DER_ERROR;
820 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
821 _asn1_set_value(p,der+counter,len3+len2);
822 counter+=len3+len2;
823 move=RIGHT;
824 break;
825 case TYPE_BIT_STRING:
826 len2=asn1_get_length_der(der+counter,len-counter,&len3);
827 if(len2 < 0) return ASN1_DER_ERROR;
828 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
829 _asn1_set_value(p,der+counter,len3+len2);
830 counter+=len3+len2;
831 move=RIGHT;
832 break;
833 case TYPE_SEQUENCE: case TYPE_SET:
834 if(move==UP){
835 len2=strtol(p->value,NULL,10);
836 _asn1_set_value(p,NULL,0);
837 if(len2==-1){ /* indefinite length method */
838 if (len-counter+1 > 0) {
839 if((der[counter]) || der[counter+1]){
840 asn1_delete_structure(element);
841 return ASN1_DER_ERROR;
843 } else return ASN1_DER_ERROR;
844 counter+=2;
846 else{ /* definite length method */
847 if(len2!=counter){
848 asn1_delete_structure(element);
849 return ASN1_DER_ERROR;
852 move=RIGHT;
854 else{ /* move==DOWN || move==RIGHT */
855 len3=asn1_get_length_der(der+counter,len-counter,&len2);
856 if(len3 < -1) return ASN1_DER_ERROR;
857 counter+=len2;
858 if(len3>0){
859 _asn1_ltostr(counter+len3,temp);
860 tlen = strlen(temp);
861 if (tlen > 0)
862 _asn1_set_value(p,temp,tlen+1);
863 move=DOWN;
865 else if(len3==0){
866 p2=p->down;
867 while(p2){
868 if(type_field(p2->type)!=TYPE_TAG){
869 p3=p2->right;
870 asn1_delete_structure(&p2);
871 p2=p3;
873 else
874 p2=p2->right;
876 move=RIGHT;
878 else{ /* indefinite length method */
879 _asn1_set_value(p,"-1",3);
880 move=DOWN;
883 break;
884 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
885 if(move==UP){
886 len2=strtol(p->value,NULL,10);
887 if(len2==-1){ /* indefinite length method */
888 if((counter+2)>len) return ASN1_DER_ERROR;
889 if((der[counter]) || der[counter+1]){
890 _asn1_append_sequence_set(p);
891 p=p->down;
892 while(p->right) p=p->right;
893 move=RIGHT;
894 continue;
896 _asn1_set_value(p,NULL,0);
897 counter+=2;
899 else{ /* definite length method */
900 if(len2>counter){
901 _asn1_append_sequence_set(p);
902 p=p->down;
903 while(p->right) p=p->right;
904 move=RIGHT;
905 continue;
907 _asn1_set_value(p,NULL,0);
908 if(len2!=counter){
909 asn1_delete_structure(element);
910 return ASN1_DER_ERROR;
914 else{ /* move==DOWN || move==RIGHT */
915 len3=asn1_get_length_der(der+counter,len-counter,&len2);
916 if(len3 < -1) return ASN1_DER_ERROR;
917 counter+=len2;
918 if(len3){
919 if(len3>0){ /* definite length method */
920 _asn1_ltostr(counter+len3,temp);
921 tlen = strlen(temp);
923 if (tlen > 0)
924 _asn1_set_value(p,temp,tlen+1);
926 else { /* indefinite length method */
927 _asn1_set_value(p,"-1",3);
929 p2=p->down;
930 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
931 if(p2->right==NULL) _asn1_append_sequence_set(p);
932 p=p2;
935 move=RIGHT;
936 break;
937 case TYPE_ANY:
938 if(asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
939 return ASN1_DER_ERROR;
940 if (counter+len2 > len)
941 return ASN1_DER_ERROR;
942 len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
943 if(len4 < -1) return ASN1_DER_ERROR;
944 if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR;
945 if(len4 != -1){
946 len2+=len4;
947 asn1_length_der(len2+len3,NULL,&len4);
948 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
949 if (temp2==NULL){
950 asn1_delete_structure(element);
951 return ASN1_MEM_ALLOC_ERROR;
954 asn1_octet_der(der+counter,len2+len3,temp2,&len4);
955 _asn1_set_value(p,temp2,len4);
956 _asn1_afree(temp2);
957 counter+=len2+len3;
959 else{ /* indefinite length */
960 /* Check indefinite lenth method in an EXPLICIT TAG */
961 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
962 indefinite=1;
963 else
964 indefinite=0;
966 len2=len-counter;
967 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
968 if(ris != ASN1_SUCCESS){
969 asn1_delete_structure(element);
970 return ris;
972 asn1_length_der(len2,NULL,&len4);
973 temp2=(unsigned char *)_asn1_alloca(len2+len4);
974 if (temp2==NULL){
975 asn1_delete_structure(element);
976 return ASN1_MEM_ALLOC_ERROR;
979 asn1_octet_der(der+counter,len2,temp2,&len4);
980 _asn1_set_value(p,temp2,len4);
981 _asn1_afree(temp2);
982 counter+=len2;
984 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
985 an indefinite length method. */
986 if(indefinite){
987 if(!der[counter] && !der[counter+1]){
988 counter+=2;
990 else{
991 asn1_delete_structure(element);
992 return ASN1_DER_ERROR;
996 move=RIGHT;
997 break;
998 default:
999 move=(move==UP)?RIGHT:DOWN;
1000 break;
1004 if(p==node && move!=DOWN) break;
1006 if(move==DOWN){
1007 if(p->down) p=p->down;
1008 else move=RIGHT;
1010 if((move==RIGHT) && !(p->type&CONST_SET)){
1011 if(p->right) p=p->right;
1012 else move=UP;
1014 if(move==UP) p=_asn1_find_up(p);
1017 _asn1_delete_not_used(*element);
1019 if(counter != len){
1020 asn1_delete_structure(element);
1021 return ASN1_DER_ERROR;
1024 return ASN1_SUCCESS;
1028 #define FOUND 1
1029 #define SAME_BRANCH 2
1030 #define OTHER_BRANCH 3
1031 #define EXIT 4
1034 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
1035 * @structure: pointer to an ASN1 structure
1036 * @elementName: name of the element to fill
1037 * @ider: vector that contains the DER encoding of the whole structure.
1038 * @len: number of bytes of *der: der[0]..der[len-1]
1039 * @errorDescription: null-terminated string contains details when an
1040 * error occurred.
1042 * Fill the element named ELEMENTNAME with values of a DER encoding
1043 * string. The sructure must just be created with function
1044 * 'create_stucture'. The DER vector must contain the encoding
1045 * string of the whole STRUCTURE. If an error occurs during the
1046 * decoding procedure, the *STRUCTURE is deleted and set equal to
1047 * %ASN1_TYPE_EMPTY.
1049 * Returns:
1051 * ASN1_SUCCESS: DER encoding OK.
1053 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or
1054 * elementName == NULL.
1056 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
1057 * the structure STRUCTURE. *ELEMENT deleted.
1060 asn1_retCode
1061 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
1062 const void *ider,int len,char *errorDescription)
1064 node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
1065 char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
1066 int nameLen=MAX_NAME_SIZE*10-1,state;
1067 int counter,len2,len3,len4,move,ris, tlen;
1068 unsigned char class,*temp2;
1069 unsigned long tag;
1070 int indefinite, result;
1071 const unsigned char* der = ider;
1073 node=*structure;
1075 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1077 if(elementName == NULL){
1078 asn1_delete_structure(structure);
1079 return ASN1_ELEMENT_NOT_FOUND;
1082 if(node->type&CONST_OPTION){
1083 asn1_delete_structure(structure);
1084 return ASN1_GENERIC_ERROR;
1087 if((*structure)->name){ /* Has *structure got a name? */
1088 nameLen-=strlen((*structure)->name);
1089 if(nameLen>0) strcpy(currentName,(*structure)->name);
1090 else{
1091 asn1_delete_structure(structure);
1092 return ASN1_MEM_ERROR;
1094 if(!(strcmp(currentName,elementName))){
1095 state=FOUND;
1096 nodeFound=*structure;
1098 else if(!memcmp(currentName,elementName,strlen(currentName)))
1099 state=SAME_BRANCH;
1100 else
1101 state=OTHER_BRANCH;
1103 else{ /* *structure doesn't have a name? */
1104 currentName[0]=0;
1105 if(elementName[0]==0){
1106 state=FOUND;
1107 nodeFound=*structure;
1109 else{
1110 state=SAME_BRANCH;
1114 counter=0;
1115 move=DOWN;
1116 p=node;
1117 while(1){
1119 ris=ASN1_SUCCESS;
1121 if(move!=UP){
1122 if(p->type&CONST_SET){
1123 p2=_asn1_find_up(p);
1124 len2=strtol(p2->value,NULL,10);
1125 if(counter==len2){
1126 p=p2;
1127 move=UP;
1128 continue;
1130 else if(counter>len2){
1131 asn1_delete_structure(structure);
1132 return ASN1_DER_ERROR;
1134 p2=p2->down;
1135 while(p2){
1136 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
1137 if(type_field(p2->type)!=TYPE_CHOICE)
1138 ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
1139 else{
1140 p3=p2->down;
1141 while(p3){
1142 ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
1143 if(ris==ASN1_SUCCESS) break;
1144 p3=p3->right;
1147 if(ris==ASN1_SUCCESS){
1148 p2->type&=~CONST_NOT_USED;
1149 p=p2;
1150 break;
1153 p2=p2->right;
1155 if(p2==NULL){
1156 asn1_delete_structure(structure);
1157 return ASN1_DER_ERROR;
1161 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1162 p2=_asn1_find_up(p);
1163 len2=strtol(p2->value,NULL,10);
1164 if(counter==len2){
1165 if(p->right){
1166 p2=p->right;
1167 move=RIGHT;
1169 else move=UP;
1171 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
1173 p=p2;
1174 continue;
1178 if(type_field(p->type)==TYPE_CHOICE){
1179 while(p->down){
1180 if(counter<len)
1181 ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
1182 else
1183 ris=ASN1_DER_ERROR;
1184 if(ris==ASN1_SUCCESS){
1185 while(p->down->right){
1186 p2=p->down->right;
1187 asn1_delete_structure(&p2);
1189 break;
1191 else if(ris==ASN1_ERROR_TYPE_ANY){
1192 asn1_delete_structure(structure);
1193 return ASN1_ERROR_TYPE_ANY;
1195 else{
1196 p2=p->down;
1197 asn1_delete_structure(&p2);
1201 if(p->down==NULL){
1202 if(!(p->type&CONST_OPTION)){
1203 asn1_delete_structure(structure);
1204 return ASN1_DER_ERROR;
1207 else
1208 p=p->down;
1211 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
1212 p2=_asn1_find_up(p);
1213 len2=strtol(p2->value,NULL,10);
1214 if(counter>len2) ris=ASN1_TAG_ERROR;
1217 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
1218 if(ris!=ASN1_SUCCESS){
1219 if(p->type&CONST_OPTION){
1220 p->type|=CONST_NOT_USED;
1221 move=RIGHT;
1223 else if(p->type&CONST_DEFAULT) {
1224 _asn1_set_value(p,NULL,0);
1225 move=RIGHT;
1227 else {
1228 if (errorDescription!=NULL)
1229 _asn1_error_description_tag_error(p,errorDescription);
1231 asn1_delete_structure(structure);
1232 return ASN1_TAG_ERROR;
1235 else counter+=len2;
1238 if(ris==ASN1_SUCCESS){
1239 switch(type_field(p->type)){
1240 case TYPE_NULL:
1241 if(der[counter]){
1242 asn1_delete_structure(structure);
1243 return ASN1_DER_ERROR;
1246 if(p==nodeFound) state=EXIT;
1248 counter++;
1249 move=RIGHT;
1250 break;
1251 case TYPE_BOOLEAN:
1252 if(der[counter++]!=1){
1253 asn1_delete_structure(structure);
1254 return ASN1_DER_ERROR;
1257 if(state==FOUND){
1258 if(der[counter++]==0) _asn1_set_value(p,"F",1);
1259 else _asn1_set_value(p,"T",1);
1261 if(p==nodeFound) state=EXIT;
1264 else
1265 counter++;
1267 move=RIGHT;
1268 break;
1269 case TYPE_INTEGER: case TYPE_ENUMERATED:
1270 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1271 if(len2 < 0) return ASN1_DER_ERROR;
1272 if(state==FOUND){
1273 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
1274 _asn1_set_value(p,der+counter,len3+len2);
1276 if(p==nodeFound) state=EXIT;
1278 counter+=len3+len2;
1279 move=RIGHT;
1280 break;
1281 case TYPE_OBJECT_ID:
1282 if(state==FOUND){
1283 _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
1284 tlen = strlen(temp);
1286 if (tlen > 0)
1287 _asn1_set_value(p,temp,tlen+1);
1289 if(p==nodeFound) state=EXIT;
1291 else{
1292 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1293 if(len2 < 0) return ASN1_DER_ERROR;
1294 len2+=len3;
1297 counter+=len2;
1298 move=RIGHT;
1299 break;
1300 case TYPE_TIME:
1301 if(state==FOUND){
1302 result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
1303 if (result != ASN1_SUCCESS) {
1304 asn1_delete_structure(structure);
1305 return result;
1308 tlen = strlen(temp);
1309 if (tlen > 0)
1310 _asn1_set_value(p,temp,tlen+1);
1312 if(p==nodeFound) state=EXIT;
1314 else{
1315 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1316 if(len2 < 0) return ASN1_DER_ERROR;
1317 len2+=len3;
1320 counter+=len2;
1321 move=RIGHT;
1322 break;
1323 case TYPE_OCTET_STRING:
1324 len3=len-counter;
1325 if(state==FOUND){
1326 ris=_asn1_get_octet_string(der+counter,p,&len3);
1327 if(p==nodeFound) state=EXIT;
1329 else
1330 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1332 if(ris != ASN1_SUCCESS) return ris;
1333 counter+=len3;
1334 move=RIGHT;
1335 break;
1336 case TYPE_GENERALSTRING:
1337 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1338 if(len2 < 0) return ASN1_DER_ERROR;
1339 if(state==FOUND){
1340 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
1341 _asn1_set_value(p,der+counter,len3+len2);
1343 if(p==nodeFound) state=EXIT;
1345 counter+=len3+len2;
1346 move=RIGHT;
1347 break;
1348 case TYPE_BIT_STRING:
1349 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1350 if(len2 < 0) return ASN1_DER_ERROR;
1351 if(state==FOUND){
1352 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
1353 _asn1_set_value(p,der+counter,len3+len2);
1355 if(p==nodeFound) state=EXIT;
1357 counter+=len3+len2;
1358 move=RIGHT;
1359 break;
1360 case TYPE_SEQUENCE: case TYPE_SET:
1361 if(move==UP){
1362 len2=strtol(p->value,NULL,10);
1363 _asn1_set_value(p,NULL,0);
1364 if(len2==-1){ /* indefinite length method */
1365 if((der[counter]) || der[counter+1]){
1366 asn1_delete_structure(structure);
1367 return ASN1_DER_ERROR;
1369 counter+=2;
1371 else{ /* definite length method */
1372 if(len2!=counter){
1373 asn1_delete_structure(structure);
1374 return ASN1_DER_ERROR;
1377 if(p==nodeFound) state=EXIT;
1378 move=RIGHT;
1380 else{ /* move==DOWN || move==RIGHT */
1381 if(state==OTHER_BRANCH){
1382 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1383 if(len3 < 0) return ASN1_DER_ERROR;
1384 counter+=len2+len3;
1385 move=RIGHT;
1387 else { /* state==SAME_BRANCH or state==FOUND */
1388 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1389 if(len3 < 0) return ASN1_DER_ERROR;
1390 counter+=len2;
1391 if(len3>0){
1392 _asn1_ltostr(counter+len3,temp);
1393 tlen = strlen(temp);
1395 if(tlen > 0)
1396 _asn1_set_value(p,temp,tlen+1);
1397 move=DOWN;
1399 else if(len3==0){
1400 p2=p->down;
1401 while(p2){
1402 if(type_field(p2->type)!=TYPE_TAG){
1403 p3=p2->right;
1404 asn1_delete_structure(&p2);
1405 p2=p3;
1407 else
1408 p2=p2->right;
1410 move=RIGHT;
1412 else{ /* indefinite length method */
1413 _asn1_set_value(p,"-1",3);
1414 move=DOWN;
1418 break;
1419 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1420 if(move==UP){
1421 len2=strtol(p->value,NULL,10);
1422 if(len2>counter){
1423 _asn1_append_sequence_set(p);
1424 p=p->down;
1425 while(p->right) p=p->right;
1426 move=RIGHT;
1427 continue;
1429 _asn1_set_value(p,NULL,0);
1430 if(len2!=counter){
1431 asn1_delete_structure(structure);
1432 return ASN1_DER_ERROR;
1435 if(p==nodeFound) state=EXIT;
1437 else{ /* move==DOWN || move==RIGHT */
1438 if(state==OTHER_BRANCH){
1439 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1440 if(len3 < 0) return ASN1_DER_ERROR;
1441 counter+=len2+len3;
1442 move=RIGHT;
1444 else{ /* state==FOUND or state==SAME_BRANCH */
1445 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1446 if(len3 < 0) return ASN1_DER_ERROR;
1447 counter+=len2;
1448 if(len3){
1449 _asn1_ltostr(counter+len3,temp);
1450 tlen = strlen(temp);
1452 if (tlen > 0)
1453 _asn1_set_value(p,temp,tlen+1);
1454 p2=p->down;
1455 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1456 if(p2->right==NULL) _asn1_append_sequence_set(p);
1457 p=p2;
1458 state=FOUND;
1463 break;
1464 case TYPE_ANY:
1465 if(asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
1466 return ASN1_DER_ERROR;
1467 if (counter+len2 > len)
1468 return ASN1_DER_ERROR;
1470 len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
1471 if(len4 < -1) return ASN1_DER_ERROR;
1473 if(len4 != -1){
1474 len2+=len4;
1475 if(state==FOUND){
1476 asn1_length_der(len2+len3,NULL,&len4);
1477 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
1478 if (temp2==NULL){
1479 asn1_delete_structure(structure);
1480 return ASN1_MEM_ALLOC_ERROR;
1483 asn1_octet_der(der+counter,len2+len3,temp2,&len4);
1484 _asn1_set_value(p,temp2,len4);
1485 _asn1_afree(temp2);
1487 if(p==nodeFound) state=EXIT;
1489 counter+=len2+len3;
1491 else{ /* indefinite length */
1492 /* Check indefinite lenth method in an EXPLICIT TAG */
1493 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1494 indefinite=1;
1495 else
1496 indefinite=0;
1498 len2=len-counter;
1499 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1500 if(ris != ASN1_SUCCESS){
1501 asn1_delete_structure(structure);
1502 return ris;
1505 if(state==FOUND){
1506 asn1_length_der(len2,NULL,&len4);
1507 temp2=(unsigned char *)_asn1_alloca(len2+len4);
1508 if (temp2==NULL){
1509 asn1_delete_structure(structure);
1510 return ASN1_MEM_ALLOC_ERROR;
1513 asn1_octet_der(der+counter,len2,temp2,&len4);
1514 _asn1_set_value(p,temp2,len4);
1515 _asn1_afree(temp2);
1517 if(p==nodeFound) state=EXIT;
1520 counter+=len2;
1522 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1523 an indefinite length method. */
1524 if(indefinite){
1525 if(!der[counter] && !der[counter+1]){
1526 counter+=2;
1528 else{
1529 asn1_delete_structure(structure);
1530 return ASN1_DER_ERROR;
1534 move=RIGHT;
1535 break;
1537 default:
1538 move=(move==UP)?RIGHT:DOWN;
1539 break;
1543 if((p==node && move!=DOWN) || (state==EXIT)) break;
1545 if(move==DOWN){
1546 if(p->down){
1547 p=p->down;
1549 if(state != FOUND){
1550 nameLen-=strlen(p->name)+1;
1551 if(nameLen>0){
1552 if(currentName[0]) strcat(currentName,".");
1553 strcat(currentName,p->name);
1555 else{
1556 asn1_delete_structure(structure);
1557 return ASN1_MEM_ERROR;
1559 if(!(strcmp(currentName,elementName))){
1560 state=FOUND;
1561 nodeFound=p;
1563 else if(!memcmp(currentName,elementName,strlen(currentName)))
1564 state=SAME_BRANCH;
1565 else
1566 state=OTHER_BRANCH;
1569 else move=RIGHT;
1572 if((move==RIGHT) && !(p->type&CONST_SET)){
1573 if(p->right){
1574 p=p->right;
1576 if(state != FOUND){
1577 dot_p=char_p=currentName;
1578 while((char_p=strchr(char_p,'.'))){
1579 dot_p=char_p++;
1580 dot_p++;
1583 nameLen+=strlen(currentName)-(dot_p-currentName);
1584 *dot_p=0;
1586 nameLen-=strlen(p->name);
1587 if(nameLen>0) strcat(currentName,p->name);
1588 else{
1589 asn1_delete_structure(structure);
1590 return ASN1_MEM_ERROR;
1593 if(!(strcmp(currentName,elementName))){
1594 state=FOUND;
1595 nodeFound=p;
1597 else if(!memcmp(currentName,elementName,strlen(currentName)))
1598 state=SAME_BRANCH;
1599 else
1600 state=OTHER_BRANCH;
1603 else move=UP;
1606 if(move==UP){
1607 p=_asn1_find_up(p);
1609 if(state != FOUND){
1610 dot_p=char_p=currentName;
1611 while((char_p=strchr(char_p,'.'))){
1612 dot_p=char_p++;
1613 dot_p++;
1616 nameLen+=strlen(currentName)-(dot_p-currentName);
1617 *dot_p=0;
1619 if(!(strcmp(currentName,elementName))){
1620 state=FOUND;
1621 nodeFound=p;
1623 else if(!memcmp(currentName,elementName,strlen(currentName)))
1624 state=SAME_BRANCH;
1625 else
1626 state=OTHER_BRANCH;
1631 _asn1_delete_not_used(*structure);
1633 if(counter > len){
1634 asn1_delete_structure(structure);
1635 return ASN1_DER_ERROR;
1638 return ASN1_SUCCESS;
1644 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
1645 * @element: pointer to an ASN1 element
1646 * @ider: vector that contains the DER encoding.
1647 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
1648 * @name_element: an element of NAME structure.
1649 * @start: the position of the first byte of NAME_ELEMENT decoding
1650 * (@ider[*start])
1651 * @end: the position of the last byte of NAME_ELEMENT decoding
1652 * (@ider[*end])
1654 * Find the start and end point of an element in a DER encoding
1655 * string. I mean that if you have a der encoding and you have
1656 * already used the function "asn1_der_decoding" to fill a structure,
1657 * it may happen that you want to find the piece of string concerning
1658 * an element of the structure.
1660 * Example: the sequence "tbsCertificate" inside an X509 certificate.
1662 * Returns:
1664 * ASN1_SUCCESS: DER encoding OK.
1666 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or
1667 * NAME_ELEMENT is not a valid element.
1669 * ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match
1670 * the structure ELEMENT.
1673 asn1_retCode
1674 asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
1675 const char *name_element,int *start, int *end)
1677 node_asn *node,*node_to_find,*p,*p2,*p3;
1678 int counter,len2,len3,len4,move,ris;
1679 unsigned char class;
1680 unsigned long tag;
1681 int indefinite;
1682 const unsigned char* der = ider;
1684 node=element;
1686 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
1688 node_to_find=_asn1_find_node(node,name_element);
1690 if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
1692 if(node_to_find==node){
1693 *start=0;
1694 *end=len-1;
1695 return ASN1_SUCCESS;
1698 if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
1700 counter=0;
1701 move=DOWN;
1702 p=node;
1703 while(1){
1704 ris=ASN1_SUCCESS;
1706 if(move!=UP){
1707 if(p->type&CONST_SET){
1708 p2=_asn1_find_up(p);
1709 len2=strtol(p2->value,NULL,10);
1710 if(len2==-1){
1711 if(!der[counter] && !der[counter+1]){
1712 p=p2;
1713 move=UP;
1714 counter+=2;
1715 continue;
1718 else if(counter==len2){
1719 p=p2;
1720 move=UP;
1721 continue;
1723 else if(counter>len2) return ASN1_DER_ERROR;
1724 p2=p2->down;
1725 while(p2){
1726 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */
1727 if(type_field(p2->type)!=TYPE_CHOICE)
1728 ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
1729 else{
1730 p3=p2->down;
1731 ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
1733 if(ris==ASN1_SUCCESS){
1734 p2->type&=~CONST_NOT_USED;
1735 p=p2;
1736 break;
1739 p2=p2->right;
1741 if(p2==NULL) return ASN1_DER_ERROR;
1744 if(p==node_to_find) *start=counter;
1746 if(type_field(p->type)==TYPE_CHOICE){
1747 p=p->down;
1748 ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
1749 if(p==node_to_find) *start=counter;
1752 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
1753 if(ris!=ASN1_SUCCESS){
1754 if(p->type&CONST_OPTION){
1755 p->type|=CONST_NOT_USED;
1756 move=RIGHT;
1758 else if(p->type&CONST_DEFAULT) {
1759 move=RIGHT;
1761 else {
1762 return ASN1_TAG_ERROR;
1765 else counter+=len2;
1768 if(ris==ASN1_SUCCESS){
1769 switch(type_field(p->type)){
1770 case TYPE_NULL:
1771 if(der[counter]) return ASN1_DER_ERROR;
1772 counter++;
1773 move=RIGHT;
1774 break;
1775 case TYPE_BOOLEAN:
1776 if(der[counter++]!=1) return ASN1_DER_ERROR;
1777 counter++;
1778 move=RIGHT;
1779 break;
1780 case TYPE_INTEGER: case TYPE_ENUMERATED:
1781 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1782 if(len2 < 0) return ASN1_DER_ERROR;
1783 counter+=len3+len2;
1784 move=RIGHT;
1785 break;
1786 case TYPE_OBJECT_ID:
1787 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1788 if(len2 < 0) return ASN1_DER_ERROR;
1789 counter+=len2+len3;
1790 move=RIGHT;
1791 break;
1792 case TYPE_TIME:
1793 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1794 if(len2 < 0) return ASN1_DER_ERROR;
1795 counter+=len2+len3;
1796 move=RIGHT;
1797 break;
1798 case TYPE_OCTET_STRING:
1799 len3=len-counter;
1800 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
1801 if(ris != ASN1_SUCCESS) return ris;
1802 counter+=len3;
1803 move=RIGHT;
1804 break;
1805 case TYPE_GENERALSTRING:
1806 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1807 if(len2 < 0) return ASN1_DER_ERROR;
1808 counter+=len3+len2;
1809 move=RIGHT;
1810 break;
1811 case TYPE_BIT_STRING:
1812 len2=asn1_get_length_der(der+counter,len-counter,&len3);
1813 if(len2 < 0) return ASN1_DER_ERROR;
1814 counter+=len3+len2;
1815 move=RIGHT;
1816 break;
1817 case TYPE_SEQUENCE: case TYPE_SET:
1818 if(move!=UP){
1819 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1820 if(len3 < -1) return ASN1_DER_ERROR;
1821 counter+=len2;
1822 if(len3==0) move=RIGHT;
1823 else move=DOWN;
1825 else{
1826 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1827 counter+=2;
1828 move=RIGHT;
1830 break;
1831 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
1832 if(move!=UP){
1833 len3=asn1_get_length_der(der+counter,len-counter,&len2);
1834 if(len3 < -1) return ASN1_DER_ERROR;
1835 counter+=len2;
1836 if((len3==-1) && !der[counter] && !der[counter+1])
1837 counter+=2;
1838 else if(len3){
1839 p2=p->down;
1840 while((type_field(p2->type)==TYPE_TAG) ||
1841 (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
1842 p=p2;
1845 else{
1846 if(!der[counter] && !der[counter+1]) /* indefinite length method */
1847 counter+=2;
1849 move=RIGHT;
1850 break;
1851 case TYPE_ANY:
1852 if (asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
1853 return ASN1_DER_ERROR;
1854 if (counter+len2 > len)
1855 return ASN1_DER_ERROR;
1857 len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
1858 if(len4 < -1) return ASN1_DER_ERROR;
1860 if(len4 != -1){
1861 counter+=len2+len4+len3;
1863 else{ /* indefinite length */
1864 /* Check indefinite lenth method in an EXPLICIT TAG */
1865 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
1866 indefinite=1;
1867 else
1868 indefinite=0;
1870 len2=len-counter;
1871 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
1872 if(ris != ASN1_SUCCESS)
1873 return ris;
1874 counter+=len2;
1876 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1877 an indefinite length method. */
1878 if(indefinite){
1879 if(!der[counter] && !der[counter+1])
1880 counter+=2;
1881 else
1882 return ASN1_DER_ERROR;
1885 move=RIGHT;
1886 break;
1887 default:
1888 move=(move==UP)?RIGHT:DOWN;
1889 break;
1893 if((p==node_to_find) && (move==RIGHT)){
1894 *end=counter-1;
1895 return ASN1_SUCCESS;
1898 if(p==node && move!=DOWN) break;
1900 if(move==DOWN){
1901 if(p->down) p=p->down;
1902 else move=RIGHT;
1904 if((move==RIGHT) && !(p->type&CONST_SET)){
1905 if(p->right) p=p->right;
1906 else move=UP;
1908 if(move==UP) p=_asn1_find_up(p);
1911 return ASN1_ELEMENT_NOT_FOUND;
1916 * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure.
1917 * @definitions: ASN1 definitions
1918 * @element: pointer to an ASN1 structure
1920 * Expands every "ANY DEFINED BY" element of a structure created from
1921 * a DER decoding process (asn1_der_decoding function). The element ANY
1922 * must be defined by an OBJECT IDENTIFIER. The type used to expand
1923 * the element ANY is the first one following the definition of
1924 * the actual value of the OBJECT IDENTIFIER.
1927 * Returns:
1929 * ASN1_SUCCESS: Substitution OK.
1931 * ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be
1932 * expanded due to a problem in OBJECT_ID -> TYPE association.
1934 * other errors: Result of der decoding process.
1937 asn1_retCode
1938 asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element)
1940 char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
1941 asn1_retCode retCode=ASN1_SUCCESS,result;
1942 int len,len2,len3;
1943 ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY;
1944 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
1946 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
1947 return ASN1_ELEMENT_NOT_FOUND;
1949 strcpy(definitionsName,definitions->name);
1950 strcat(definitionsName,".");
1952 p=*element;
1953 while(p){
1955 switch(type_field(p->type)){
1956 case TYPE_ANY:
1957 if((p->type&CONST_DEFINED_BY) && (p->value)){
1958 /* search the "DEF_BY" element */
1959 p2=p->down;
1960 while((p2) && (type_field(p2->type)!=TYPE_CONSTANT))
1961 p2=p2->right;
1963 if(!p2){
1964 retCode=ASN1_ERROR_TYPE_ANY;
1965 break;
1968 p3=_asn1_find_up(p);
1970 if(!p3){
1971 retCode=ASN1_ERROR_TYPE_ANY;
1972 break;
1975 p3=p3->down;
1976 while(p3){
1977 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1978 p3=p3->right;
1981 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
1982 (p3->value==NULL)){
1984 p3=_asn1_find_up(p);
1985 p3=_asn1_find_up(p3);
1987 if(!p3){
1988 retCode=ASN1_ERROR_TYPE_ANY;
1989 break;
1992 p3=p3->down;
1994 while(p3){
1995 if((p3->name) && !(strcmp(p3->name,p2->name))) break;
1996 p3=p3->right;
1999 if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
2000 (p3->value==NULL)){
2001 retCode=ASN1_ERROR_TYPE_ANY;
2002 break;
2006 /* search the OBJECT_ID into definitions */
2007 p2=definitions->down;
2008 while(p2){
2009 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
2010 (p2->type & CONST_ASSIGN)){
2011 strcpy(name,definitionsName);
2012 strcat(name,p2->name);
2014 len=MAX_NAME_SIZE;
2015 result=asn1_read_value(definitions,name,value,&len);
2017 if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){
2018 p2=p2->right; /* pointer to the structure to
2019 use for expansion */
2020 while((p2) && (p2->type & CONST_ASSIGN))
2021 p2=p2->right;
2023 if(p2){
2024 strcpy(name,definitionsName);
2025 strcat(name,p2->name);
2027 result=asn1_create_element(definitions,name,&aux);
2028 if(result == ASN1_SUCCESS){
2029 _asn1_set_name(aux,p->name);
2030 len2=asn1_get_length_der(p->value,p->value_len,&len3);
2031 if(len2 < 0) return ASN1_DER_ERROR;
2033 result=asn1_der_decoding(&aux,p->value+len3,len2,
2034 errorDescription);
2035 if(result == ASN1_SUCCESS){
2037 _asn1_set_right(aux,p->right);
2038 _asn1_set_right(p,aux);
2040 result=asn1_delete_structure(&p);
2041 if(result == ASN1_SUCCESS){
2042 p=aux;
2043 aux=ASN1_TYPE_EMPTY;
2044 break;
2046 else{ /* error with asn1_delete_structure */
2047 asn1_delete_structure(&aux);
2048 retCode=result;
2049 break;
2052 else{/* error with asn1_der_decoding */
2053 retCode=result;
2054 break;
2057 else{/* error with asn1_create_element */
2058 retCode=result;
2059 break;
2062 else{/* error with the pointer to the structure to exapand */
2063 retCode=ASN1_ERROR_TYPE_ANY;
2064 break;
2068 p2=p2->right;
2069 } /* end while */
2071 if(!p2){
2072 retCode=ASN1_ERROR_TYPE_ANY;
2073 break;
2077 break;
2078 default:
2079 break;
2083 if(p->down){
2084 p=p->down;
2086 else if(p==*element){
2087 p=NULL;
2088 break;
2090 else if(p->right) p=p->right;
2091 else{
2092 while(1){
2093 p=_asn1_find_up(p);
2094 if(p==*element){
2095 p=NULL;
2096 break;
2098 if(p->right){
2099 p=p->right;
2100 break;
2106 return retCode;
2112 * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure.
2113 * @definitions: ASN1 definitions
2114 * @element: pointer to an ASN1 structure
2115 * @octetName: name of the OCTECT STRING field to expand.
2116 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2117 * the type for expansion.
2119 * Expands an "OCTET STRING" element of a structure created from a
2120 * DER decoding process (asn1_der_decoding function). The type used
2121 * for expansion is the first one following the definition of the
2122 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2124 * Returns:
2126 * ASN1_SUCCESS: Substitution OK.
2128 * ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct.
2130 * ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use
2131 * for expansion.
2133 * other errors: result of der decoding process.
2135 asn1_retCode
2136 asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element,
2137 const char *octetName,const char *objectName)
2139 char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE];
2140 asn1_retCode retCode=ASN1_SUCCESS,result;
2141 int len,len2,len3;
2142 ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY;
2143 ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY;
2144 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
2146 if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY))
2147 return ASN1_ELEMENT_NOT_FOUND;
2149 octetNode=_asn1_find_node(*element,octetName);
2150 if(octetNode==ASN1_TYPE_EMPTY)
2151 return ASN1_ELEMENT_NOT_FOUND;
2152 if(type_field(octetNode->type)!=TYPE_OCTET_STRING)
2153 return ASN1_ELEMENT_NOT_FOUND;
2154 if(octetNode->value==NULL)
2155 return ASN1_VALUE_NOT_FOUND;
2157 objectNode=_asn1_find_node(*element,objectName);
2158 if(objectNode==ASN1_TYPE_EMPTY)
2159 return ASN1_ELEMENT_NOT_FOUND;
2161 if(type_field(objectNode->type)!=TYPE_OBJECT_ID)
2162 return ASN1_ELEMENT_NOT_FOUND;
2164 if(objectNode->value==NULL)
2165 return ASN1_VALUE_NOT_FOUND;
2168 /* search the OBJECT_ID into definitions */
2169 p2=definitions->down;
2170 while(p2){
2171 if((type_field(p2->type)==TYPE_OBJECT_ID) &&
2172 (p2->type & CONST_ASSIGN)){
2173 strcpy(name,definitions->name);
2174 strcat(name,".");
2175 strcat(name,p2->name);
2177 len = sizeof(value);
2178 result=asn1_read_value(definitions,name,value,&len);
2180 if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){
2182 p2=p2->right; /* pointer to the structure to
2183 use for expansion */
2184 while((p2) && (p2->type & CONST_ASSIGN))
2185 p2=p2->right;
2187 if(p2){
2188 strcpy(name,definitions->name);
2189 strcat(name,".");
2190 strcat(name,p2->name);
2192 result=asn1_create_element(definitions,name,&aux);
2193 if(result == ASN1_SUCCESS){
2194 _asn1_set_name(aux,octetNode->name);
2195 len2=asn1_get_length_der(octetNode->value,octetNode->value_len,&len3);
2196 if(len2 < 0) return ASN1_DER_ERROR;
2198 result=asn1_der_decoding(&aux,octetNode->value+len3,len2,
2199 errorDescription);
2200 if(result == ASN1_SUCCESS){
2202 _asn1_set_right(aux,octetNode->right);
2203 _asn1_set_right(octetNode,aux);
2205 result=asn1_delete_structure(&octetNode);
2206 if(result == ASN1_SUCCESS){
2207 aux=ASN1_TYPE_EMPTY;
2208 break;
2210 else{ /* error with asn1_delete_structure */
2211 asn1_delete_structure(&aux);
2212 retCode=result;
2213 break;
2216 else{/* error with asn1_der_decoding */
2217 retCode=result;
2218 break;
2221 else{/* error with asn1_create_element */
2222 retCode=result;
2223 break;
2226 else{/* error with the pointer to the structure to exapand */
2227 retCode=ASN1_VALUE_NOT_VALID;
2228 break;
2233 p2=p2->right;
2237 if(!p2) retCode=ASN1_VALUE_NOT_VALID;
2239 return retCode;