00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <int.h>
00028 #include <errors.h>
00029 #include "der.h"
00030 #include "parser_aux.h"
00031 #include <gstr.h>
00032 #include "structure.h"
00033 #include "element.h"
00034
00035
00036 void
00037 _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription)
00038 {
00039
00040 Estrcpy(ErrorDescription,":: tag error near element '");
00041 _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription),
00042 MAX_ERROR_DESCRIPTION_SIZE-40);
00043 Estrcat(ErrorDescription,"'");
00044
00045 }
00046
00047
00048 signed long
00049 _asn1_get_length_der(const unsigned char *der, int der_len, int *len)
00050 {
00051 unsigned long ans;
00052 int k,punt;
00053
00054 *len = 0;
00055 if (der_len <= 0) return 0;
00056
00057 if(!(der[0]&128)){
00058
00059 *len=1;
00060 return der[0];
00061 }
00062 else{
00063
00064 k=der[0]&0x7F;
00065 punt=1;
00066 if(k){
00067 ans=0;
00068 while(punt<=k && punt < der_len) {
00069 unsigned long last = ans;
00070 ans=ans*256+der[punt++];
00071 if (ans < last)
00072
00073 return -2;
00074 }
00075 }
00076 else{
00077 ans=-1;
00078 }
00079
00080 *len=punt;
00081 return ans;
00082 }
00083 }
00084
00085
00086
00087
00088 int
00089 _asn1_get_tag_der(const unsigned char *der, int der_len,
00090 unsigned char *class,int *len, unsigned long *tag)
00091 {
00092 int punt,ris;
00093
00094 if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR;
00095
00096 *class=der[0]&0xE0;
00097 if((der[0]&0x1F)!=0x1F){
00098
00099 *len=1;
00100 ris=der[0]&0x1F;
00101 }
00102 else{
00103
00104 punt=1;
00105 ris=0;
00106 while(punt <= der_len && der[punt]&128)
00107 {
00108 int last = ris;
00109 ris=ris*128+(der[punt++]&0x7F);
00110 if (ris < last)
00111
00112 return ASN1_DER_ERROR;
00113 }
00114 if (punt >= der_len)
00115 return ASN1_DER_ERROR;
00116 {
00117 int last = ris;
00118 ris=ris*128+(der[punt++]&0x7F);
00119 if (ris < last)
00120
00121 return ASN1_DER_ERROR;
00122 }
00123 *len=punt;
00124 }
00125 if (tag) *tag = ris;
00126 return ASN1_SUCCESS;
00127 }
00128
00129
00130
00131
00132 int
00133 _asn1_get_octet_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size, int *str_len)
00134 {
00135 int len_len;
00136
00137 if (der_len <= 0) return ASN1_GENERIC_ERROR;
00138
00139
00140 *str_len=_asn1_get_length_der(der, der_len, &len_len);
00141
00142 if (*str_len < 0)
00143 return ASN1_DER_ERROR;
00144
00145 *ret_len=*str_len+len_len;
00146 if ( str_size >= *str_len)
00147 memcpy(str,der+len_len,*str_len);
00148 else {
00149 return ASN1_MEM_ERROR;
00150 }
00151
00152 return ASN1_SUCCESS;
00153 }
00154
00155
00156
00157
00158
00159 int
00160 _asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size)
00161 {
00162 int len_len,str_len;
00163
00164 if(der_len <=0 || str==NULL) return ASN1_DER_ERROR;
00165 str_len=_asn1_get_length_der(der, der_len, &len_len);
00166 if (str_len < 0 || str_size < str_len)
00167 return ASN1_DER_ERROR;
00168 memcpy(str,der+len_len,str_len);
00169 str[str_len]=0;
00170 *ret_len=str_len+len_len;
00171
00172 return ASN1_SUCCESS;
00173 }
00174
00175
00176
00177 void
00178 _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size)
00179 {
00180 int len_len,len,k;
00181 char temp[20];
00182 unsigned long val,val1;
00183
00184 *ret_len = 0;
00185 if (str && str_size > 0) str[0] = 0;
00186
00187 if(str==NULL || der_len <= 0) return;
00188 len=_asn1_get_length_der(der,der_len, &len_len);
00189
00190 if (len < 0 || len > der_len || len_len > der_len) return;
00191
00192 val1=der[len_len]/40;
00193 val=der[len_len]-val1*40;
00194
00195 _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp));
00196 _asn1_str_cat(str, str_size, ".");
00197 _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp));
00198
00199 val=0;
00200 for(k=1;k<len;k++){
00201 val=val<<7;
00202 val|=der[len_len+k]&0x7F;
00203 if(!(der[len_len+k]&0x80)){
00204 _asn1_str_cat(str, str_size,".");
00205 _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp));
00206 val=0;
00207 }
00208 }
00209 *ret_len=len+len_len;
00210 }
00211
00212
00213
00214
00215 int
00216 _asn1_get_bit_der(const unsigned char *der, int der_len,
00217 int *ret_len,unsigned char *str, int str_size, int *bit_len)
00218 {
00219 int len_len,len_byte;
00220
00221 if (der_len <=0) return ASN1_GENERIC_ERROR;
00222 len_byte=_asn1_get_length_der(der,der_len,&len_len)-1;
00223 if (len_byte < 0)
00224 return ASN1_DER_ERROR;
00225
00226 *ret_len=len_byte+len_len+1;
00227 *bit_len=len_byte*8-der[len_len];
00228
00229 if (str_size >= len_byte)
00230 memcpy(str,der+len_len+1,len_byte);
00231 else {
00232 return ASN1_MEM_ERROR;
00233 }
00234
00235 return ASN1_SUCCESS;
00236 }
00237
00238
00239
00240
00241 int
00242 _asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len)
00243 {
00244 node_asn *p;
00245 int counter,len2,len3,is_tag_implicit;
00246 unsigned long tag,tag_implicit=0;
00247 unsigned char class,class2,class_implicit=0;
00248
00249 if (der_len <= 0) return ASN1_GENERIC_ERROR;
00250
00251 counter=is_tag_implicit=0;
00252
00253 if(node->type&CONST_TAG){
00254 p=node->down;
00255 while(p){
00256 if(type_field(p->type)==TYPE_TAG){
00257 if(p->type&CONST_APPLICATION) class2=APPLICATION;
00258 else if(p->type&CONST_UNIVERSAL) class2=UNIVERSAL;
00259 else if(p->type&CONST_PRIVATE) class2=PRIVATE;
00260 else class2=CONTEXT_SPECIFIC;
00261
00262 if(p->type&CONST_EXPLICIT){
00263 if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
00264 return ASN1_DER_ERROR;
00265 if (counter+len2 > der_len)
00266 return ASN1_DER_ERROR;
00267 counter+=len2;
00268 len3=_asn1_get_length_der(der+counter,der_len-counter, &len2);
00269 if (len3 < 0)
00270 return ASN1_DER_ERROR;
00271 counter+=len2;
00272 if(!is_tag_implicit){
00273 if((class!=(class2|STRUCTURED)) || (tag!=strtoul(p->value,NULL,10)))
00274 return ASN1_TAG_ERROR;
00275 }
00276 else{
00277 if((class!=class_implicit) || (tag!=tag_implicit))
00278 return ASN1_TAG_ERROR;
00279 }
00280
00281 is_tag_implicit=0;
00282 }
00283 else{
00284 if(!is_tag_implicit){
00285 if((type_field(node->type)==TYPE_SEQUENCE) ||
00286 (type_field(node->type)==TYPE_SEQUENCE_OF) ||
00287 (type_field(node->type)==TYPE_SET) ||
00288 (type_field(node->type)==TYPE_SET_OF)) class2|=STRUCTURED;
00289 class_implicit=class2;
00290 tag_implicit=strtoul(p->value,NULL,10);
00291 is_tag_implicit=1;
00292 }
00293 }
00294 }
00295 p=p->right;
00296 }
00297 }
00298
00299 if(is_tag_implicit){
00300 if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS)
00301 return ASN1_DER_ERROR;
00302 if (counter+len2 > der_len)
00303 return ASN1_DER_ERROR;
00304
00305 if((class!=class_implicit) || (tag!=tag_implicit)){
00306 if(type_field(node->type)==TYPE_OCTET_STRING){
00307 class_implicit |= STRUCTURED;
00308 if((class!=class_implicit) || (tag!=tag_implicit))
00309 return ASN1_TAG_ERROR;
00310 }
00311 else
00312 return ASN1_TAG_ERROR;
00313 }
00314 }
00315 else{
00316 if(type_field(node->type)==TYPE_TAG){
00317 counter=0;
00318 *ret_len=counter;
00319 return ASN1_SUCCESS;
00320 }
00321
00322 if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
00323 return ASN1_DER_ERROR;
00324 if (counter+len2 > der_len)
00325 return ASN1_DER_ERROR;
00326
00327 switch(type_field(node->type)){
00328 case TYPE_NULL:
00329 if((class!=UNIVERSAL) || (tag!=TAG_NULL)) return ASN1_DER_ERROR;
00330 break;
00331 case TYPE_BOOLEAN:
00332 if((class!=UNIVERSAL) || (tag!=TAG_BOOLEAN)) return ASN1_DER_ERROR;
00333 break;
00334 case TYPE_INTEGER:
00335 if((class!=UNIVERSAL) || (tag!=TAG_INTEGER)) return ASN1_DER_ERROR;
00336 break;
00337 case TYPE_ENUMERATED:
00338 if((class!=UNIVERSAL) || (tag!=TAG_ENUMERATED)) return ASN1_DER_ERROR;
00339 break;
00340 case TYPE_OBJECT_ID:
00341 if((class!=UNIVERSAL) || (tag!=TAG_OBJECT_ID)) return ASN1_DER_ERROR;
00342 break;
00343 case TYPE_TIME:
00344 if(node->type&CONST_UTC){
00345 if((class!=UNIVERSAL) || (tag!=TAG_UTCTime)) return ASN1_DER_ERROR;
00346 }
00347 else{
00348 if((class!=UNIVERSAL) || (tag!=TAG_GENERALIZEDTime))
00349 return ASN1_DER_ERROR;
00350 }
00351 break;
00352 case TYPE_OCTET_STRING:
00353 if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED)))
00354 || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR;
00355 break;
00356 case TYPE_GENERALSTRING:
00357 if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR;
00358 break;
00359 case TYPE_BIT_STRING:
00360 if((class!=UNIVERSAL) || (tag!=TAG_BIT_STRING)) return ASN1_DER_ERROR;
00361 break;
00362 case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF:
00363 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SEQUENCE))
00364 return ASN1_DER_ERROR;
00365 break;
00366 case TYPE_SET: case TYPE_SET_OF:
00367 if((class!=(UNIVERSAL|STRUCTURED)) || (tag!=TAG_SET))
00368 return ASN1_DER_ERROR;
00369 break;
00370 case TYPE_ANY:
00371 counter-=len2;
00372 break;
00373 default:
00374 return ASN1_DER_ERROR;
00375 break;
00376 }
00377 }
00378
00379 counter+=len2;
00380 *ret_len=counter;
00381 return ASN1_SUCCESS;
00382 }
00383
00384
00385 int
00386 _asn1_delete_not_used(node_asn *node)
00387 {
00388 node_asn *p,*p2;
00389
00390 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00391
00392 p=node;
00393 while(p){
00394 if(p->type&CONST_NOT_USED){
00395 p2=NULL;
00396 if(p!=node){
00397 p2=_asn1_find_left(p);
00398 if(!p2) p2=_asn1_find_up(p);
00399 }
00400 asn1_delete_structure(&p);
00401 p=p2;
00402 }
00403
00404 if(!p) break;
00405
00406 if(p->down){
00407 p=p->down;
00408 }
00409 else{
00410 if(p==node) p=NULL;
00411 else if(p->right) p=p->right;
00412 else{
00413 while(1){
00414 p=_asn1_find_up(p);
00415 if(p==node){
00416 p=NULL;
00417 break;
00418 }
00419 if(p->right){
00420 p=p->right;
00421 break;
00422 }
00423 }
00424 }
00425 }
00426 }
00427 return ASN1_SUCCESS;
00428 }
00429
00430
00431 asn1_retCode
00432 _asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len)
00433 {
00434 int len2,len3,counter,counter2,counter_end,tot_len,indefinite;
00435 char *temp,*temp2;
00436
00437 counter=0;
00438
00439 if(*(der-1) & STRUCTURED){
00440 tot_len=0;
00441 indefinite=_asn1_get_length_der(der, *len, &len3);
00442 if (indefinite < -1)
00443 return ASN1_DER_ERROR;
00444
00445 counter+=len3;
00446 if(indefinite>=0) indefinite+=len3;
00447
00448 while(1){
00449 if(counter>(*len)) return ASN1_DER_ERROR;
00450
00451 if(indefinite==-1){
00452 if((der[counter]==0) && (der[counter+1]==0)){
00453 counter+=2;
00454 break;
00455 }
00456 }
00457 else if(counter>=indefinite) break;
00458
00459 if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR;
00460
00461 counter++;
00462
00463 len2=_asn1_get_length_der(der+counter,*len-counter, &len3);
00464 if(len2 <= 0) return ASN1_DER_ERROR;
00465
00466 counter+=len3+len2;
00467 tot_len+=len2;
00468 }
00469
00470
00471 if(node){
00472 _asn1_length_der(tot_len,NULL,&len2);
00473 temp=(unsigned char *)_asn1_alloca(len2+tot_len);
00474 if (temp==NULL){
00475 return ASN1_MEM_ALLOC_ERROR;
00476 }
00477
00478 _asn1_length_der(tot_len,temp,&len2);
00479 tot_len+=len2;
00480 temp2=temp+len2;
00481 len2=_asn1_get_length_der(der,*len,&len3);
00482 if(len2 < -1) return ASN1_DER_ERROR;
00483 counter2=len3+1;
00484
00485 if(indefinite==-1) counter_end=counter-2;
00486 else counter_end=counter;
00487
00488 while(counter2<counter_end){
00489 len2=_asn1_get_length_der(der+counter2, *len-counter, &len3);
00490 if(len2 < -1) return ASN1_DER_ERROR;
00491
00492
00493
00494
00495 memcpy(temp2,der+counter2+len3,len2);
00496 temp2+=len2;
00497 counter2+=len2+len3+1;
00498 }
00499
00500 _asn1_set_value(node,temp,tot_len);
00501 _asn1_afree(temp);
00502 }
00503 }
00504 else{
00505 len2=_asn1_get_length_der(der, *len, &len3);
00506 if(len2 < 0) return ASN1_DER_ERROR;
00507 if (len3+len2 > *len) return ASN1_DER_ERROR;
00508 if(node)
00509 _asn1_set_value(node,der,len3+len2);
00510 counter=len3+len2;
00511 }
00512
00513 *len=counter;
00514 return ASN1_SUCCESS;
00515
00516 }
00517
00518
00519 asn1_retCode
00520 _asn1_get_indefinite_length_string(const unsigned char* der, int* len)
00521 {
00522 int len2,len3,counter,indefinite;
00523 unsigned long tag;
00524 unsigned char class;
00525
00526 counter=indefinite=0;
00527
00528 while(1){
00529 if((*len)<counter) return ASN1_DER_ERROR;
00530
00531 if((der[counter]==0) && (der[counter+1]==0)){
00532 counter+=2;
00533 indefinite--;
00534 if(indefinite<=0) break;
00535 else continue;
00536 }
00537
00538 if(_asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
00539 return ASN1_DER_ERROR;
00540 if (counter+len2 > *len)
00541 return ASN1_DER_ERROR;
00542 counter+=len2;
00543 len2=_asn1_get_length_der(der+counter, *len-counter,&len3);
00544 if(len2 < -1) return ASN1_DER_ERROR;
00545 if(len2 == -1){
00546 indefinite++;
00547 counter+=1;
00548 }
00549 else{
00550 counter+=len2+len3;
00551 }
00552 }
00553
00554 *len=counter;
00555 return ASN1_SUCCESS;
00556
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 asn1_retCode
00582 asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len,
00583 char *errorDescription)
00584 {
00585 node_asn *node,*p,*p2,*p3;
00586 char temp[128];
00587 int counter,len2,len3,len4,move,ris;
00588 unsigned char class,*temp2;
00589 unsigned long tag;
00590 int indefinite, result;
00591 const unsigned char* der = ider;
00592
00593 node=*element;
00594
00595 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
00596
00597 if(node->type&CONST_OPTION){
00598 asn1_delete_structure(element);
00599 return ASN1_GENERIC_ERROR;
00600 }
00601
00602 counter=0;
00603 move=DOWN;
00604 p=node;
00605 while(1){
00606 ris=ASN1_SUCCESS;
00607 if(move!=UP){
00608 if(p->type&CONST_SET){
00609 p2=_asn1_find_up(p);
00610 len2=strtol(p2->value,NULL,10);
00611 if(len2==-1){
00612 if(!der[counter] && !der[counter+1]){
00613 p=p2;
00614 move=UP;
00615 counter+=2;
00616 continue;
00617 }
00618 }
00619 else if(counter==len2){
00620 p=p2;
00621 move=UP;
00622 continue;
00623 }
00624 else if(counter>len2){
00625 asn1_delete_structure(element);
00626 return ASN1_DER_ERROR;
00627 }
00628 p2=p2->down;
00629 while(p2){
00630 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
00631 if(type_field(p2->type)!=TYPE_CHOICE)
00632 ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2);
00633 else{
00634 p3=p2->down;
00635 while(p3){
00636 ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2);
00637 if(ris==ASN1_SUCCESS) break;
00638 p3=p3->right;
00639 }
00640 }
00641 if(ris==ASN1_SUCCESS){
00642 p2->type&=~CONST_NOT_USED;
00643 p=p2;
00644 break;
00645 }
00646 }
00647 p2=p2->right;
00648 }
00649 if(p2==NULL){
00650 asn1_delete_structure(element);
00651 return ASN1_DER_ERROR;
00652 }
00653 }
00654
00655 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
00656 p2=_asn1_find_up(p);
00657 len2=strtol(p2->value,NULL,10);
00658 if(counter==len2){
00659 if(p->right){
00660 p2=p->right;
00661 move=RIGHT;
00662 }
00663 else move=UP;
00664
00665 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
00666
00667 p=p2;
00668 continue;
00669 }
00670 }
00671
00672 if(type_field(p->type)==TYPE_CHOICE){
00673 while(p->down){
00674 if(counter<len)
00675 ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
00676 else
00677 ris=ASN1_DER_ERROR;
00678 if(ris==ASN1_SUCCESS){
00679 while(p->down->right){
00680 p2=p->down->right;
00681 asn1_delete_structure(&p2);
00682 }
00683 break;
00684 }
00685 else if(ris==ASN1_ERROR_TYPE_ANY){
00686 asn1_delete_structure(element);
00687 return ASN1_ERROR_TYPE_ANY;
00688 }
00689 else{
00690 p2=p->down;
00691 asn1_delete_structure(&p2);
00692 }
00693 }
00694
00695 if(p->down==NULL){
00696 if(!(p->type&CONST_OPTION)){
00697 asn1_delete_structure(element);
00698 return ASN1_DER_ERROR;
00699 }
00700 }
00701 else
00702 p=p->down;
00703 }
00704
00705 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
00706 p2=_asn1_find_up(p);
00707 len2=strtol(p2->value,NULL,10);
00708 if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR;
00709 }
00710
00711 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
00712 if(ris!=ASN1_SUCCESS){
00713 if(p->type&CONST_OPTION){
00714 p->type|=CONST_NOT_USED;
00715 move=RIGHT;
00716 }
00717 else if(p->type&CONST_DEFAULT) {
00718 _asn1_set_value(p,NULL,0);
00719 move=RIGHT;
00720 }
00721 else {
00722 if (errorDescription!=NULL)
00723 _asn1_error_description_tag_error(p,errorDescription);
00724
00725 asn1_delete_structure(element);
00726 return ASN1_TAG_ERROR;
00727 }
00728 }
00729 else counter+=len2;
00730 }
00731
00732 if(ris==ASN1_SUCCESS){
00733 switch(type_field(p->type)){
00734 case TYPE_NULL:
00735 if(der[counter]){
00736 asn1_delete_structure(element);
00737 return ASN1_DER_ERROR;
00738 }
00739 counter++;
00740 move=RIGHT;
00741 break;
00742 case TYPE_BOOLEAN:
00743 if(der[counter++]!=1){
00744 asn1_delete_structure(element);
00745 return ASN1_DER_ERROR;
00746 }
00747 if(der[counter++]==0) _asn1_set_value(p,"F",1);
00748 else _asn1_set_value(p,"T",1);
00749 move=RIGHT;
00750 break;
00751 case TYPE_INTEGER: case TYPE_ENUMERATED:
00752 len2=_asn1_get_length_der(der+counter,len-counter, &len3);
00753 if(len2 < 0) return ASN1_DER_ERROR;
00754 if (len2+len3 > len-counter) return ASN1_DER_ERROR;
00755 _asn1_set_value(p,der+counter,len3+len2);
00756 counter+=len3+len2;
00757 move=RIGHT;
00758 break;
00759 case TYPE_OBJECT_ID:
00760 _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
00761 _asn1_set_value(p,temp,strlen(temp)+1);
00762 counter+=len2;
00763 move=RIGHT;
00764 break;
00765 case TYPE_TIME:
00766 result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
00767 if (result != ASN1_SUCCESS) {
00768 asn1_delete_structure(element);
00769 return result;
00770 }
00771 _asn1_set_value(p,temp,strlen(temp)+1);
00772 counter+=len2;
00773 move=RIGHT;
00774 break;
00775 case TYPE_OCTET_STRING:
00776 len3=len-counter;
00777 ris=_asn1_get_octet_string(der+counter,p,&len3);
00778 if(ris != ASN1_SUCCESS) return ris;
00779 counter+=len3;
00780 move=RIGHT;
00781 break;
00782 case TYPE_GENERALSTRING:
00783 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
00784 if(len2 < 0) return ASN1_DER_ERROR;
00785 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
00786 _asn1_set_value(p,der+counter,len3+len2);
00787 counter+=len3+len2;
00788 move=RIGHT;
00789 break;
00790 case TYPE_BIT_STRING:
00791 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
00792 if(len2 < 0) return ASN1_DER_ERROR;
00793 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
00794 _asn1_set_value(p,der+counter,len3+len2);
00795 counter+=len3+len2;
00796 move=RIGHT;
00797 break;
00798 case TYPE_SEQUENCE: case TYPE_SET:;
00799 if(move==UP){
00800 len2=strtol(p->value,NULL,10);
00801 _asn1_set_value(p,NULL,0);
00802 if(len2==-1){
00803 if (len-counter+1 > 0) {
00804 if((der[counter]) || der[counter+1]){
00805 asn1_delete_structure(element);
00806 return ASN1_DER_ERROR;
00807 }
00808 } else return ASN1_DER_ERROR;
00809 counter+=2;
00810 }
00811 else{
00812 if(len2!=counter){
00813 asn1_delete_structure(element);
00814 return ASN1_DER_ERROR;
00815 }
00816 }
00817 move=RIGHT;
00818 }
00819 else{
00820 len3=_asn1_get_length_der(der+counter,len-counter,&len2);
00821 if(len3 < -1) return ASN1_DER_ERROR;
00822 counter+=len2;
00823 if(len3>0){
00824 _asn1_ltostr(counter+len3,temp);
00825 _asn1_set_value(p,temp,strlen(temp)+1);
00826 move=DOWN;
00827 }
00828 else if(len3==0){
00829 p2=p->down;
00830 while(p2){
00831 if(type_field(p2->type)!=TYPE_TAG){
00832 p3=p2->right;
00833 asn1_delete_structure(&p2);
00834 p2=p3;
00835 }
00836 else
00837 p2=p2->right;
00838 }
00839 move=RIGHT;
00840 }
00841 else{
00842 _asn1_set_value(p,"-1",3);
00843 move=DOWN;
00844 }
00845 }
00846 break;
00847 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
00848 if(move==UP){
00849 len2=strtol(p->value,NULL,10);
00850 if(len2==-1){
00851 if((counter+2)>len) return ASN1_DER_ERROR;
00852 if((der[counter]) || der[counter+1]){
00853 _asn1_append_sequence_set(p);
00854 p=p->down;
00855 while(p->right) p=p->right;
00856 move=RIGHT;
00857 continue;
00858 }
00859 _asn1_set_value(p,NULL,0);
00860 counter+=2;
00861 }
00862 else{
00863 if(len2>counter){
00864 _asn1_append_sequence_set(p);
00865 p=p->down;
00866 while(p->right) p=p->right;
00867 move=RIGHT;
00868 continue;
00869 }
00870 _asn1_set_value(p,NULL,0);
00871 if(len2!=counter){
00872 asn1_delete_structure(element);
00873 return ASN1_DER_ERROR;
00874 }
00875 }
00876 }
00877 else{
00878 len3=_asn1_get_length_der(der+counter,len-counter,&len2);
00879 if(len3 < -1) return ASN1_DER_ERROR;
00880 counter+=len2;
00881 if(len3){
00882 if(len3>0){
00883 _asn1_ltostr(counter+len3,temp);
00884 _asn1_set_value(p,temp,strlen(temp)+1);
00885 }
00886 else {
00887 _asn1_set_value(p,"-1",3);
00888 }
00889 p2=p->down;
00890 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
00891 if(p2->right==NULL) _asn1_append_sequence_set(p);
00892 p=p2;
00893 }
00894 }
00895 move=RIGHT;
00896 break;
00897 case TYPE_ANY:
00898
00899 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
00900 indefinite=1;
00901 else
00902 indefinite=0;
00903
00904 if(_asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
00905 return ASN1_DER_ERROR;
00906 if (counter+len2 > len)
00907 return ASN1_DER_ERROR;
00908 len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
00909 if(len4 < -1) return ASN1_DER_ERROR;
00910 if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR;
00911
00912 if(len4 != -1){
00913 len2+=len4;
00914 _asn1_length_der(len2+len3,NULL,&len4);
00915 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
00916 if (temp2==NULL){
00917 asn1_delete_structure(element);
00918 return ASN1_MEM_ALLOC_ERROR;
00919 }
00920
00921 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
00922 _asn1_set_value(p,temp2,len4);
00923 _asn1_afree(temp2);
00924 counter+=len2+len3;
00925 }
00926 else{
00927 len2=len-counter;
00928 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
00929 if(ris != ASN1_SUCCESS){
00930 asn1_delete_structure(element);
00931 return ris;
00932 }
00933 _asn1_length_der(len2,NULL,&len4);
00934 temp2=(unsigned char *)_asn1_alloca(len2+len4);
00935 if (temp2==NULL){
00936 asn1_delete_structure(element);
00937 return ASN1_MEM_ALLOC_ERROR;
00938 }
00939
00940 _asn1_octet_der(der+counter,len2,temp2,&len4);
00941 _asn1_set_value(p,temp2,len4);
00942 _asn1_afree(temp2);
00943 counter+=len2;
00944 }
00945
00946
00947
00948 if(indefinite){
00949 if(!der[counter] && !der[counter+1]){
00950 counter+=2;
00951 }
00952 else{
00953 asn1_delete_structure(element);
00954 return ASN1_DER_ERROR;
00955 }
00956 }
00957 move=RIGHT;
00958 break;
00959 default:
00960 move=(move==UP)?RIGHT:DOWN;
00961 break;
00962 }
00963 }
00964
00965 if(p==node && move!=DOWN) break;
00966
00967 if(move==DOWN){
00968 if(p->down) p=p->down;
00969 else move=RIGHT;
00970 }
00971 if((move==RIGHT) && !(p->type&CONST_SET)){
00972 if(p->right) p=p->right;
00973 else move=UP;
00974 }
00975 if(move==UP) p=_asn1_find_up(p);
00976 }
00977
00978 _asn1_delete_not_used(*element);
00979
00980 if(counter != len){
00981 asn1_delete_structure(element);
00982 return ASN1_DER_ERROR;
00983 }
00984
00985 return ASN1_SUCCESS;
00986 }
00987
00988
00989 #define FOUND 1
00990 #define SAME_BRANCH 2
00991 #define OTHER_BRANCH 3
00992 #define EXIT 4
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 asn1_retCode
01020 asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName,
01021 const void *ider,int len,char *errorDescription)
01022 {
01023 node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY;
01024 char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p;
01025 int nameLen=MAX_NAME_SIZE*10-1,state;
01026 int counter,len2,len3,len4,move,ris;
01027 unsigned char class,*temp2;
01028 unsigned long tag;
01029 int indefinite, result;
01030 const unsigned char* der = ider;
01031
01032 node=*structure;
01033
01034 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
01035
01036 if(elementName == NULL){
01037 asn1_delete_structure(structure);
01038 return ASN1_ELEMENT_NOT_FOUND;
01039 }
01040
01041 if(node->type&CONST_OPTION){
01042 asn1_delete_structure(structure);
01043 return ASN1_GENERIC_ERROR;
01044 }
01045
01046 if((*structure)->name){
01047 nameLen-=strlen((*structure)->name);
01048 if(nameLen>0) strcpy(currentName,(*structure)->name);
01049 else{
01050 asn1_delete_structure(structure);
01051 return ASN1_MEM_ERROR;
01052 }
01053 if(!(strcmp(currentName,elementName))){
01054 state=FOUND;
01055 nodeFound=*structure;
01056 }
01057 else if(!memcmp(currentName,elementName,strlen(currentName)))
01058 state=SAME_BRANCH;
01059 else
01060 state=OTHER_BRANCH;
01061 }
01062 else{
01063 currentName[0]=0;
01064 if(elementName[0]==0){
01065 state=FOUND;
01066 nodeFound=*structure;
01067 }
01068 else{
01069 state=SAME_BRANCH;
01070 }
01071 }
01072
01073 counter=0;
01074 move=DOWN;
01075 p=node;
01076 while(1){
01077
01078 ris=ASN1_SUCCESS;
01079
01080 if(move!=UP){
01081 if(p->type&CONST_SET){
01082 p2=_asn1_find_up(p);
01083 len2=strtol(p2->value,NULL,10);
01084 if(counter==len2){
01085 p=p2;
01086 move=UP;
01087 continue;
01088 }
01089 else if(counter>len2){
01090 asn1_delete_structure(structure);
01091 return ASN1_DER_ERROR;
01092 }
01093 p2=p2->down;
01094 while(p2){
01095 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
01096 if(type_field(p2->type)!=TYPE_CHOICE)
01097 ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
01098 else{
01099 p3=p2->down;
01100 while(p3){
01101 ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
01102 if(ris==ASN1_SUCCESS) break;
01103 p3=p3->right;
01104 }
01105 }
01106 if(ris==ASN1_SUCCESS){
01107 p2->type&=~CONST_NOT_USED;
01108 p=p2;
01109 break;
01110 }
01111 }
01112 p2=p2->right;
01113 }
01114 if(p2==NULL){
01115 asn1_delete_structure(structure);
01116 return ASN1_DER_ERROR;
01117 }
01118 }
01119
01120 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
01121 p2=_asn1_find_up(p);
01122 len2=strtol(p2->value,NULL,10);
01123 if(counter==len2){
01124 if(p->right){
01125 p2=p->right;
01126 move=RIGHT;
01127 }
01128 else move=UP;
01129
01130 if(p->type&CONST_OPTION) asn1_delete_structure(&p);
01131
01132 p=p2;
01133 continue;
01134 }
01135 }
01136
01137 if(type_field(p->type)==TYPE_CHOICE){
01138 while(p->down){
01139 if(counter<len)
01140 ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2);
01141 else
01142 ris=ASN1_DER_ERROR;
01143 if(ris==ASN1_SUCCESS){
01144 while(p->down->right){
01145 p2=p->down->right;
01146 asn1_delete_structure(&p2);
01147 }
01148 break;
01149 }
01150 else if(ris==ASN1_ERROR_TYPE_ANY){
01151 asn1_delete_structure(structure);
01152 return ASN1_ERROR_TYPE_ANY;
01153 }
01154 else{
01155 p2=p->down;
01156 asn1_delete_structure(&p2);
01157 }
01158 }
01159
01160 if(p->down==NULL){
01161 if(!(p->type&CONST_OPTION)){
01162 asn1_delete_structure(structure);
01163 return ASN1_DER_ERROR;
01164 }
01165 }
01166 else
01167 p=p->down;
01168 }
01169
01170 if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){
01171 p2=_asn1_find_up(p);
01172 len2=strtol(p2->value,NULL,10);
01173 if(counter>len2) ris=ASN1_TAG_ERROR;
01174 }
01175
01176 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
01177 if(ris!=ASN1_SUCCESS){
01178 if(p->type&CONST_OPTION){
01179 p->type|=CONST_NOT_USED;
01180 move=RIGHT;
01181 }
01182 else if(p->type&CONST_DEFAULT) {
01183 _asn1_set_value(p,NULL,0);
01184 move=RIGHT;
01185 }
01186 else {
01187 if (errorDescription!=NULL)
01188 _asn1_error_description_tag_error(p,errorDescription);
01189
01190 asn1_delete_structure(structure);
01191 return ASN1_TAG_ERROR;
01192 }
01193 }
01194 else counter+=len2;
01195 }
01196
01197 if(ris==ASN1_SUCCESS){
01198 switch(type_field(p->type)){
01199 case TYPE_NULL:
01200 if(der[counter]){
01201 asn1_delete_structure(structure);
01202 return ASN1_DER_ERROR;
01203 }
01204
01205 if(p==nodeFound) state=EXIT;
01206
01207 counter++;
01208 move=RIGHT;
01209 break;
01210 case TYPE_BOOLEAN:
01211 if(der[counter++]!=1){
01212 asn1_delete_structure(structure);
01213 return ASN1_DER_ERROR;
01214 }
01215
01216 if(state==FOUND){
01217 if(der[counter++]==0) _asn1_set_value(p,"F",1);
01218 else _asn1_set_value(p,"T",1);
01219
01220 if(p==nodeFound) state=EXIT;
01221
01222 }
01223 else
01224 counter++;
01225
01226 move=RIGHT;
01227 break;
01228 case TYPE_INTEGER: case TYPE_ENUMERATED:
01229 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01230 if(len2 < 0) return ASN1_DER_ERROR;
01231 if(state==FOUND){
01232 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
01233 _asn1_set_value(p,der+counter,len3+len2);
01234
01235 if(p==nodeFound) state=EXIT;
01236 }
01237 counter+=len3+len2;
01238 move=RIGHT;
01239 break;
01240 case TYPE_OBJECT_ID:
01241 if(state==FOUND){
01242 _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp));
01243 _asn1_set_value(p,temp,strlen(temp)+1);
01244
01245 if(p==nodeFound) state=EXIT;
01246 }
01247 else{
01248 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01249 if(len2 < 0) return ASN1_DER_ERROR;
01250 len2+=len3;
01251 }
01252
01253 counter+=len2;
01254 move=RIGHT;
01255 break;
01256 case TYPE_TIME:
01257 if(state==FOUND){
01258 result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1);
01259 if (result != ASN1_SUCCESS) {
01260 asn1_delete_structure(structure);
01261 return result;
01262 }
01263
01264 _asn1_set_value(p,temp,strlen(temp)+1);
01265
01266 if(p==nodeFound) state=EXIT;
01267 }
01268 else{
01269 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01270 if(len2 < 0) return ASN1_DER_ERROR;
01271 len2+=len3;
01272 }
01273
01274 counter+=len2;
01275 move=RIGHT;
01276 break;
01277 case TYPE_OCTET_STRING:
01278 len3=len-counter;
01279 if(state==FOUND){
01280 ris=_asn1_get_octet_string(der+counter,p,&len3);
01281 if(p==nodeFound) state=EXIT;
01282 }
01283 else
01284 ris=_asn1_get_octet_string(der+counter,NULL,&len3);
01285
01286 if(ris != ASN1_SUCCESS) return ris;
01287 counter+=len3;
01288 move=RIGHT;
01289 break;
01290 case TYPE_GENERALSTRING:
01291 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01292 if(len2 < 0) return ASN1_DER_ERROR;
01293 if(state==FOUND){
01294 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
01295 _asn1_set_value(p,der+counter,len3+len2);
01296
01297 if(p==nodeFound) state=EXIT;
01298 }
01299 counter+=len3+len2;
01300 move=RIGHT;
01301 break;
01302 case TYPE_BIT_STRING:
01303 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01304 if(len2 < 0) return ASN1_DER_ERROR;
01305 if(state==FOUND){
01306 if (len3+len2 > len-counter) return ASN1_DER_ERROR;
01307 _asn1_set_value(p,der+counter,len3+len2);
01308
01309 if(p==nodeFound) state=EXIT;
01310 }
01311 counter+=len3+len2;
01312 move=RIGHT;
01313 break;
01314 case TYPE_SEQUENCE: case TYPE_SET:
01315 if(move==UP){
01316 len2=strtol(p->value,NULL,10);
01317 _asn1_set_value(p,NULL,0);
01318 if(len2==-1){
01319 if((der[counter]) || der[counter+1]){
01320 asn1_delete_structure(structure);
01321 return ASN1_DER_ERROR;
01322 }
01323 counter+=2;
01324 }
01325 else{
01326 if(len2!=counter){
01327 asn1_delete_structure(structure);
01328 return ASN1_DER_ERROR;
01329 }
01330 }
01331 if(p==nodeFound) state=EXIT;
01332 move=RIGHT;
01333 }
01334 else{
01335 if(state==OTHER_BRANCH){
01336 len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01337 if(len3 < 0) return ASN1_DER_ERROR;
01338 counter+=len2+len3;
01339 move=RIGHT;
01340 }
01341 else {
01342 len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01343 if(len3 < 0) return ASN1_DER_ERROR;
01344 counter+=len2;
01345 if(len3>0){
01346 _asn1_ltostr(counter+len3,temp);
01347 _asn1_set_value(p,temp,strlen(temp)+1);
01348 move=DOWN;
01349 }
01350 else if(len3==0){
01351 p2=p->down;
01352 while(p2){
01353 if(type_field(p2->type)!=TYPE_TAG){
01354 p3=p2->right;
01355 asn1_delete_structure(&p2);
01356 p2=p3;
01357 }
01358 else
01359 p2=p2->right;
01360 }
01361 move=RIGHT;
01362 }
01363 else{
01364 _asn1_set_value(p,"-1",3);
01365 move=DOWN;
01366 }
01367 }
01368 }
01369 break;
01370 case TYPE_SEQUENCE_OF: case TYPE_SET_OF:
01371 if(move==UP){
01372 len2=strtol(p->value,NULL,10);
01373 if(len2>counter){
01374 _asn1_append_sequence_set(p);
01375 p=p->down;
01376 while(p->right) p=p->right;
01377 move=RIGHT;
01378 continue;
01379 }
01380 _asn1_set_value(p,NULL,0);
01381 if(len2!=counter){
01382 asn1_delete_structure(structure);
01383 return ASN1_DER_ERROR;
01384 }
01385
01386 if(p==nodeFound) state=EXIT;
01387 }
01388 else{
01389 if(state==OTHER_BRANCH){
01390 len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01391 if(len3 < 0) return ASN1_DER_ERROR;
01392 counter+=len2+len3;
01393 move=RIGHT;
01394 }
01395 else{
01396 len3=_asn1_get_length_der(der+counter,len-counter,&len2);
01397 if(len3 < 0) return ASN1_DER_ERROR;
01398 counter+=len2;
01399 if(len3){
01400 _asn1_ltostr(counter+len3,temp);
01401 _asn1_set_value(p,temp,strlen(temp)+1);
01402 p2=p->down;
01403 while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right;
01404 if(p2->right==NULL) _asn1_append_sequence_set(p);
01405 p=p2;
01406 state=FOUND;
01407 }
01408 }
01409 }
01410
01411 break;
01412 case TYPE_ANY:
01413
01414 if((p->type&CONST_TAG) && (der[counter-1]==0x80))
01415 indefinite=1;
01416 else
01417 indefinite=0;
01418
01419 if(_asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS)
01420 return ASN1_DER_ERROR;
01421 if (counter+len2 > len)
01422 return ASN1_DER_ERROR;
01423
01424 len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3);
01425 if(len4 < -1) return ASN1_DER_ERROR;
01426
01427 if(len4 != -1){
01428 len2+=len4;
01429 if(state==FOUND){
01430 _asn1_length_der(len2+len3,NULL,&len4);
01431 temp2=(unsigned char *)_asn1_alloca(len2+len3+len4);
01432 if (temp2==NULL){
01433 asn1_delete_structure(structure);
01434 return ASN1_MEM_ALLOC_ERROR;
01435 }
01436
01437 _asn1_octet_der(der+counter,len2+len3,temp2,&len4);
01438 _asn1_set_value(p,temp2,len4);
01439 _asn1_afree(temp2);
01440
01441 if(p==nodeFound) state=EXIT;
01442 }
01443 counter+=len2+len3;
01444 }
01445 else{
01446 len2=len-counter;
01447 ris=_asn1_get_indefinite_length_string(der+counter,&len2);
01448 if(ris != ASN1_SUCCESS){
01449 asn1_delete_structure(structure);
01450 return ris;
01451 }
01452
01453 if(state==FOUND){
01454 _asn1_length_der(len2,NULL,&len4);
01455 temp2=(unsigned char *)_asn1_alloca(len2+len4);
01456 if (temp2==NULL){
01457 asn1_delete_structure(structure);
01458 return ASN1_MEM_ALLOC_ERROR;
01459 }
01460
01461 _asn1_octet_der(der+counter,len2,temp2,&len4);
01462 _asn1_set_value(p,temp2,len4);
01463 _asn1_afree(temp2);
01464
01465 if(p==nodeFound) state=EXIT;
01466 }
01467
01468 counter+=len2;
01469 }
01470
01471
01472
01473 if(indefinite){
01474 if(!der[counter] && !der[counter+1]){
01475 counter+=2;
01476 }
01477 else{
01478 asn1_delete_structure(structure);
01479 return ASN1_DER_ERROR;
01480 }
01481 }
01482 move=RIGHT;
01483 break;
01484
01485 default:
01486 move=(move==UP)?RIGHT:DOWN;
01487 break;
01488 }
01489 }
01490
01491 if((p==node && move!=DOWN) || (state==EXIT)) break;
01492
01493 if(move==DOWN){
01494 if(p->down){
01495 p=p->down;
01496
01497 if(state != FOUND){
01498 nameLen-=strlen(p->name)+1;
01499 if(nameLen>0){
01500 if(currentName[0]) strcat(currentName,".");
01501 strcat(currentName,p->name);
01502 }
01503 else{
01504 asn1_delete_structure(structure);
01505 return ASN1_MEM_ERROR;
01506 }
01507 if(!(strcmp(currentName,elementName))){
01508 state=FOUND;
01509 nodeFound=p;
01510 }
01511 else if(!memcmp(currentName,elementName,strlen(currentName)))
01512 state=SAME_BRANCH;
01513 else
01514 state=OTHER_BRANCH;
01515 }
01516 }
01517 else move=RIGHT;
01518 }
01519
01520 if((move==RIGHT) && !(p->type&CONST_SET)){
01521 if(p->right){
01522 p=p->right;
01523
01524 if(state != FOUND){
01525 dot_p=char_p=currentName;
01526 while((char_p=strchr(char_p,'.'))){
01527 dot_p=char_p++;
01528 dot_p++;
01529 }
01530
01531 nameLen+=strlen(currentName)-(dot_p-currentName);
01532 *dot_p=0;
01533
01534 nameLen-=strlen(p->name);
01535 if(nameLen>0) strcat(currentName,p->name);
01536 else{
01537 asn1_delete_structure(structure);
01538 return ASN1_MEM_ERROR;
01539 }
01540
01541 if(!(strcmp(currentName,elementName))){
01542 state=FOUND;
01543 nodeFound=p;
01544 }
01545 else if(!memcmp(currentName,elementName,strlen(currentName)))
01546 state=SAME_BRANCH;
01547 else
01548 state=OTHER_BRANCH;
01549 }
01550 }
01551 else move=UP;
01552 }
01553
01554 if(move==UP){
01555 p=_asn1_find_up(p);
01556
01557 if(state != FOUND){
01558 dot_p=char_p=currentName;
01559 while((char_p=strchr(char_p,'.'))){
01560 dot_p=char_p++;
01561 dot_p++;
01562 }
01563
01564 nameLen+=strlen(currentName)-(dot_p-currentName);
01565 *dot_p=0;
01566
01567 if(!(strcmp(currentName,elementName))){
01568 state=FOUND;
01569 nodeFound=p;
01570 }
01571 else if(!memcmp(currentName,elementName,strlen(currentName)))
01572 state=SAME_BRANCH;
01573 else
01574 state=OTHER_BRANCH;
01575 }
01576 }
01577 }
01578
01579 _asn1_delete_not_used(*structure);
01580
01581 if(counter > len){
01582 asn1_delete_structure(structure);
01583 return ASN1_DER_ERROR;
01584 }
01585
01586 return ASN1_SUCCESS;
01587 }
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616 asn1_retCode
01617 asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len,
01618 const char *name_element,int *start, int *end)
01619 {
01620 node_asn *node,*node_to_find,*p,*p2,*p3;
01621 int counter,len2,len3,len4,move,ris;
01622 unsigned char class;
01623 unsigned long tag;
01624 int indefinite;
01625 const unsigned char* der = ider;
01626
01627 node=element;
01628
01629 if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND;
01630
01631 node_to_find=_asn1_find_node(node,name_element);
01632
01633 if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND;
01634
01635 if(node_to_find==node){
01636 *start=0;
01637 *end=len-1;
01638 return ASN1_SUCCESS;
01639 }
01640
01641 if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR;
01642
01643 counter=0;
01644 move=DOWN;
01645 p=node;
01646 while(1){
01647 ris=ASN1_SUCCESS;
01648
01649 if(move!=UP){
01650 if(p->type&CONST_SET){
01651 p2=_asn1_find_up(p);
01652 len2=strtol(p2->value,NULL,10);
01653 if(len2==-1){
01654 if(!der[counter] && !der[counter+1]){
01655 p=p2;
01656 move=UP;
01657 counter+=2;
01658 continue;
01659 }
01660 }
01661 else if(counter==len2){
01662 p=p2;
01663 move=UP;
01664 continue;
01665 }
01666 else if(counter>len2) return ASN1_DER_ERROR;
01667 p2=p2->down;
01668 while(p2){
01669 if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){
01670 if(type_field(p2->type)!=TYPE_CHOICE)
01671 ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2);
01672 else{
01673 p3=p2->down;
01674 ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2);
01675 }
01676 if(ris==ASN1_SUCCESS){
01677 p2->type&=~CONST_NOT_USED;
01678 p=p2;
01679 break;
01680 }
01681 }
01682 p2=p2->right;
01683 }
01684 if(p2==NULL) return ASN1_DER_ERROR;
01685 }
01686
01687 if(p==node_to_find) *start=counter;
01688
01689 if(type_field(p->type)==TYPE_CHOICE){
01690 p=p->down;
01691 ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
01692 if(p==node_to_find) *start=counter;
01693 }
01694
01695 if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2);
01696 if(ris!=ASN1_SUCCESS){
01697 if(p->type&CONST_OPTION){
01698 p->type|=CONST_NOT_USED;
01699 move=RIGHT;
01700 }
01701 else if(p->type&CONST_DEFAULT) {
01702 move=RIGHT;
01703 }
01704 else {
01705 return ASN1_TAG_ERROR;
01706 }
01707 }
01708 else counter+=len2;
01709 }
01710
01711 if(ris==ASN1_SUCCESS){
01712 switch(type_field(p->type)){
01713 case TYPE_NULL:
01714 if(der[counter]) return ASN1_DER_ERROR;
01715 counter++;
01716 move=RIGHT;
01717 break;
01718 case TYPE_BOOLEAN:
01719 if(der[counter++]!=1) return ASN1_DER_ERROR;
01720 counter++;
01721 move=RIGHT;
01722 break;
01723 case TYPE_INTEGER: case TYPE_ENUMERATED:
01724 len2=_asn1_get_length_der(der+counter,len-counter,&len3);
01725 if(len2 < 0) return ASN1_DER_ERROR;
01726 counter+=len3+len2;
01727 move=RIGHT;