00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <int.h>
00022 #include <errors.h>
00023 #include "parser_aux.h"
00024 #include "der.h"
00025 #include "gstr.h"
00026 #include "structure.h"
00027 #include "element.h"
00028
00029 char _asn1_identifierMissing[MAX_NAME_SIZE+1];
00030
00031
00032
00033
00034
00035
00036 typedef struct list_struct{
00037 node_asn *node;
00038 struct list_struct *next;
00039 } list_type;
00040
00041
00042
00043 list_type *firstElement=NULL;
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 node_asn *
00055 _asn1_add_node(unsigned int type)
00056 {
00057 list_type *listElement;
00058 node_asn *punt;
00059
00060 punt=(node_asn *) _asn1_malloc(sizeof(node_asn));
00061 if (punt==NULL) return NULL;
00062
00063 listElement=(list_type *) _asn1_malloc(sizeof(list_type));
00064 if(listElement==NULL){
00065 _asn1_free(punt);
00066 return NULL;
00067 }
00068
00069 listElement->node=punt;
00070 listElement->next=firstElement;
00071 firstElement=listElement;
00072
00073 punt->left=NULL;
00074 punt->name=NULL;
00075 punt->type=type;
00076 punt->value=NULL;
00077 punt->down=NULL;
00078 punt->right=NULL;
00079
00080 return punt;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 node_asn *
00097 _asn1_find_node(node_asn *pointer,const char *name)
00098 {
00099 node_asn *p;
00100 char *n_end,n[MAX_NAME_SIZE+1];
00101 const char *n_start;
00102
00103 if(pointer == NULL) return NULL;
00104
00105 if(name==NULL) return NULL;
00106
00107 p=pointer;
00108 n_start=name;
00109
00110 if(p->name != NULL){
00111 n_end=strchr(n_start,'.');
00112 if(n_end){
00113 memcpy(n,n_start,n_end-n_start);
00114 n[n_end-n_start]=0;
00115 n_start=n_end;
00116 n_start++;
00117 }
00118 else{
00119 _asn1_str_cpy(n,sizeof(n),n_start);
00120 n_start=NULL;
00121 }
00122
00123 while(p){
00124 if((p->name) && (!strcmp(p->name,n))) break;
00125 else p=p->right;
00126 }
00127
00128 if(p==NULL) return NULL;
00129 }
00130 else{
00131 if(n_start[0]==0)
00132 return p;
00133 }
00134
00135 while(n_start){
00136 n_end=strchr(n_start,'.');
00137 if(n_end){
00138 memcpy(n,n_start,n_end-n_start);
00139 n[n_end-n_start]=0;
00140 n_start=n_end;
00141 n_start++;
00142 }
00143 else{
00144 _asn1_str_cpy(n,sizeof(n),n_start);
00145 n_start=NULL;
00146 }
00147
00148 if(p->down==NULL) return NULL;
00149
00150 p=p->down;
00151
00152
00153
00154 if(!strcmp(n,"?LAST")){
00155 if(p==NULL) return NULL;
00156 while(p->right) p=p->right;
00157 }
00158 else{
00159 while(p){
00160 if((p->name) && (!strcmp(p->name,n))) break;
00161 else p=p->right;
00162 }
00163 if(p==NULL) return NULL;
00164 }
00165 }
00166
00167 return p;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 node_asn *
00182 _asn1_set_value(node_asn *node,const unsigned char *value,unsigned int len)
00183 {
00184
00185 if(node==NULL) return node;
00186 if(node->value){
00187 _asn1_free(node->value);
00188 node->value=NULL;
00189 node->value_len = 0;
00190 }
00191 if(!len) return node;
00192 node->value=(unsigned char *) _asn1_malloc(len);
00193 if (node->value==NULL) return NULL;
00194 node->value_len = len;
00195
00196 memcpy(node->value,value,len);
00197 return node;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 node_asn *
00211 _asn1_set_name(node_asn *node,const char *name)
00212 {
00213 if(node==NULL) return node;
00214
00215 if(node->name){
00216 _asn1_free(node->name);
00217 node->name=NULL;
00218 }
00219
00220 if(name==NULL) return node;
00221
00222 if(strlen(name))
00223 {
00224 node->name=(char *) _asn1_strdup( name);
00225 if (node->name==NULL) return NULL;
00226 }
00227 else node->name=NULL;
00228 return node;
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 node_asn *
00241 _asn1_set_right(node_asn *node,node_asn *right)
00242 {
00243 if(node==NULL) return node;
00244 node->right=right;
00245 if(right) right->left=node;
00246 return node;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 node_asn *
00258 _asn1_get_right(node_asn *node)
00259 {
00260 if(node==NULL) return NULL;
00261 return node->right;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271 node_asn *
00272 _asn1_get_last_right(node_asn *node)
00273 {
00274 node_asn *p;
00275
00276 if(node==NULL) return NULL;
00277 p=node;
00278 while(p->right) p=p->right;
00279 return p;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 node_asn *
00292 _asn1_set_down(node_asn *node,node_asn *down)
00293 {
00294 if(node==NULL) return node;
00295 node->down=down;
00296 if(down) down->left=node;
00297 return node;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 node_asn *
00309 _asn1_get_down(node_asn *node)
00310 {
00311 if(node==NULL) return NULL;
00312 return node->down;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322 char *
00323 _asn1_get_name(node_asn *node)
00324 {
00325 if(node==NULL) return NULL;
00326 return node->name;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 node_asn *
00341 _asn1_mod_type(node_asn *node,unsigned int value)
00342 {
00343 if(node==NULL) return node;
00344 node->type|=value;
00345 return node;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 void
00357 _asn1_remove_node(node_asn *node)
00358 {
00359 if(node==NULL) return;
00360
00361 if (node->name!=NULL)
00362 _asn1_free(node->name);
00363 if (node->value!=NULL)
00364 _asn1_free(node->value);
00365 _asn1_free(node);
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375 node_asn *
00376 _asn1_find_up(node_asn *node)
00377 {
00378 node_asn *p;
00379
00380 if(node==NULL) return NULL;
00381
00382 p=node;
00383
00384 while((p->left!=NULL) && (p->left->right==p)) p=p->left;
00385
00386 return p->left;
00387 }
00388
00389
00390
00391
00392
00393
00394 void
00395 _asn1_delete_list(void)
00396 {
00397 list_type *listElement;
00398
00399 while(firstElement){
00400 listElement=firstElement;
00401 firstElement=firstElement->next;
00402 _asn1_free(listElement);
00403 }
00404 }
00405
00406
00407
00408
00409
00410
00411 void
00412 _asn1_delete_list_and_nodes(void)
00413 {
00414 list_type *listElement;
00415
00416 while(firstElement){
00417 listElement=firstElement;
00418 firstElement=firstElement->next;
00419 _asn1_remove_node(listElement->node);
00420 _asn1_free(listElement);
00421 }
00422 }
00423
00424
00425 char *
00426 _asn1_ltostr(long v,char *str)
00427 {
00428 long d,r;
00429 char temp[20];
00430 int count,k,start;
00431
00432 if(v<0){
00433 str[0]='-';
00434 start=1;
00435 v=-v;
00436 }
00437 else start=0;
00438
00439 count=0;
00440 do{
00441 d=v/10;
00442 r=v-d*10;
00443 temp[start+count]='0'+(char)r;
00444 count++;
00445 v=d;
00446 }while(v);
00447
00448 for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1];
00449 str[count+start]=0;
00450 return str;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 asn1_retCode
00465 _asn1_change_integer_value(ASN1_TYPE node)
00466 {
00467 node_asn *p;
00468 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
00469 unsigned char val2[SIZEOF_UNSIGNED_LONG_INT+1];
00470 int len;
00471
00472 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00473
00474 p=node;
00475 while(p){
00476 if((type_field(p->type)==TYPE_INTEGER) && (p->type&CONST_ASSIGN)){
00477 if(p->value){
00478 _asn1_convert_integer(p->value,val,sizeof(val), &len);
00479 _asn1_octet_der(val,len,val2,&len);
00480 _asn1_set_value(p,val2,len);
00481 }
00482 }
00483
00484 if(p->down){
00485 p=p->down;
00486 }
00487 else{
00488 if(p==node) p=NULL;
00489 else if(p->right) p=p->right;
00490 else{
00491 while(1){
00492 p=_asn1_find_up(p);
00493 if(p==node){
00494 p=NULL;
00495 break;
00496 }
00497 if(p->right){
00498 p=p->right;
00499 break;
00500 }
00501 }
00502 }
00503 }
00504 }
00505
00506 return ASN1_SUCCESS;
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 asn1_retCode
00520 _asn1_expand_object_id(ASN1_TYPE node)
00521 {
00522 node_asn *p,*p2,*p3,*p4,*p5;
00523 char name_root[MAX_NAME_SIZE],name2[2*MAX_NAME_SIZE+1];
00524 int move;
00525
00526 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00527
00528 _asn1_str_cpy(name_root, sizeof(name_root), node->name);
00529
00530 p=node;
00531 move=DOWN;
00532
00533 while(!((p==node) && (move==UP))){
00534 if(move!=UP){
00535 if((type_field(p->type)==TYPE_OBJECT_ID) && (p->type&CONST_ASSIGN)){
00536 p2=p->down;
00537 if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
00538 if(p2->value && !isdigit(p2->value[0])){
00539 _asn1_str_cpy(name2, sizeof(name2), name_root);
00540 _asn1_str_cat(name2, sizeof(name2), ".");
00541 _asn1_str_cat(name2, sizeof(name2), p2->value);
00542 p3=_asn1_find_node(node,name2);
00543 if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
00544 !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND;
00545 _asn1_set_down(p,p2->right);
00546 _asn1_remove_node(p2);
00547 p2=p;
00548 p4=p3->down;
00549 while(p4){
00550 if(type_field(p4->type)==TYPE_CONSTANT){
00551 p5=_asn1_add_node_only(TYPE_CONSTANT);
00552 _asn1_set_name(p5,p4->name);
00553 _asn1_set_value(p5,p4->value,strlen(p4->value)+1);
00554 if(p2==p){
00555 _asn1_set_right(p5,p->down);
00556 _asn1_set_down(p,p5);
00557 }
00558 else{
00559 _asn1_set_right(p5,p2->right);
00560 _asn1_set_right(p2,p5);
00561 }
00562 p2=p5;
00563 }
00564 p4=p4->right;
00565 }
00566 move=DOWN;
00567 continue;
00568 }
00569 }
00570 }
00571 move=DOWN;
00572 }
00573 else move=RIGHT;
00574
00575 if(move==DOWN){
00576 if(p->down) p=p->down;
00577 else move=RIGHT;
00578 }
00579
00580 if(p==node) {move=UP; continue;}
00581
00582 if(move==RIGHT){
00583 if(p->right) p=p->right;
00584 else move=UP;
00585 }
00586 if(move==UP) p=_asn1_find_up(p);
00587 }
00588
00589
00590
00591
00592
00593 p=node;
00594 move=DOWN;
00595
00596 while(!((p==node) && (move==UP))){
00597 if(move!=UP){
00598 if((type_field(p->type)==TYPE_OBJECT_ID) &&
00599 (p->type&CONST_DEFAULT)){
00600 p2=p->down;
00601 if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
00602 _asn1_str_cpy(name2, sizeof(name2), name_root);
00603 _asn1_str_cat(name2, sizeof(name2), ".");
00604 _asn1_str_cat(name2, sizeof(name2), p2->value);
00605 p3=_asn1_find_node(node,name2);
00606 if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
00607 !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND;
00608 p4=p3->down;
00609 name2[0]=0;
00610 while(p4){
00611 if(type_field(p4->type)==TYPE_CONSTANT){
00612 if(name2[0]) _asn1_str_cat(name2,sizeof(name2),".");
00613 _asn1_str_cat(name2,sizeof(name2),p4->value);
00614 }
00615 p4=p4->right;
00616 }
00617 _asn1_set_value(p2,name2,strlen(name2)+1);
00618 }
00619 }
00620 move=DOWN;
00621 }
00622 else move=RIGHT;
00623
00624 if(move==DOWN){
00625 if(p->down) p=p->down;
00626 else move=RIGHT;
00627 }
00628
00629 if(p==node) {move=UP; continue;}
00630
00631 if(move==RIGHT){
00632 if(p->right) p=p->right;
00633 else move=UP;
00634 }
00635 if(move==UP) p=_asn1_find_up(p);
00636 }
00637
00638 return ASN1_SUCCESS;
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 asn1_retCode
00653 _asn1_type_set_config(ASN1_TYPE node)
00654 {
00655 node_asn *p,*p2;
00656 int move;
00657
00658 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00659
00660 p=node;
00661 move=DOWN;
00662
00663 while(!((p==node) && (move==UP))){
00664 if(move!=UP){
00665 if(type_field(p->type)==TYPE_SET){
00666 p2=p->down;
00667 while(p2){
00668 if(type_field(p2->type)!=TYPE_TAG)
00669 p2->type|=CONST_SET|CONST_NOT_USED;
00670 p2=p2->right;
00671 }
00672 }
00673 move=DOWN;
00674 }
00675 else move=RIGHT;
00676
00677 if(move==DOWN){
00678 if(p->down) p=p->down;
00679 else move=RIGHT;
00680 }
00681
00682 if(p==node) {move=UP; continue;}
00683
00684 if(move==RIGHT){
00685 if(p->right) p=p->right;
00686 else move=UP;
00687 }
00688 if(move==UP) p=_asn1_find_up(p);
00689 }
00690
00691 return ASN1_SUCCESS;
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 asn1_retCode
00709 _asn1_check_identifier(ASN1_TYPE node)
00710 {
00711 node_asn *p,*p2;
00712 char name2[MAX_NAME_SIZE*2+2];
00713
00714 if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
00715
00716 p=node;
00717 while(p){
00718 if(type_field(p->type)==TYPE_IDENTIFIER){
00719 _asn1_str_cpy(name2, sizeof(name2), node->name);
00720 _asn1_str_cat(name2, sizeof(name2), ".");
00721 _asn1_str_cat(name2, sizeof(name2), p->value);
00722 p2=_asn1_find_node(node,name2);
00723 if(p2==NULL){
00724 strcpy(_asn1_identifierMissing,p->value);
00725 return ASN1_IDENTIFIER_NOT_FOUND;
00726 }
00727 }
00728 else if((type_field(p->type)==TYPE_OBJECT_ID) &&
00729 (p->type&CONST_DEFAULT)){
00730 p2=p->down;
00731 if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
00732 _asn1_str_cpy(name2, sizeof(name2), node->name);
00733 _asn1_str_cat(name2, sizeof(name2), ".");
00734 _asn1_str_cat(name2, sizeof(name2), p2->value);
00735 strcpy(_asn1_identifierMissing,p2->value);
00736 p2=_asn1_find_node(node,name2);
00737 if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
00738 !(p2->type&CONST_ASSIGN))
00739 return ASN1_IDENTIFIER_NOT_FOUND;
00740 else
00741 _asn1_identifierMissing[0]=0;
00742 }
00743 }
00744 else if((type_field(p->type)==TYPE_OBJECT_ID) &&
00745 (p->type&CONST_ASSIGN)){
00746 p2=p->down;
00747 if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){
00748 if(p2->value && !isdigit(p2->value[0])){
00749 _asn1_str_cpy(name2, sizeof(name2), node->name);
00750 _asn1_str_cat(name2, sizeof(name2), ".");
00751 _asn1_str_cat(name2, sizeof(name2), p2->value);
00752 strcpy(_asn1_identifierMissing,p2->value);
00753 p2=_asn1_find_node(node,name2);
00754 if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
00755 !(p2->type&CONST_ASSIGN))
00756 return ASN1_IDENTIFIER_NOT_FOUND;
00757 else
00758 _asn1_identifierMissing[0]=0;
00759 }
00760 }
00761 }
00762
00763 if(p->down){
00764 p=p->down;
00765 }
00766 else if(p->right) p=p->right;
00767 else{
00768 while(1){
00769 p=_asn1_find_up(p);
00770 if(p==node){
00771 p=NULL;
00772 break;
00773 }
00774 if(p->right){
00775 p=p->right;
00776 break;
00777 }
00778 }
00779 }
00780 }
00781
00782 return ASN1_SUCCESS;
00783 }
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 asn1_retCode
00798 _asn1_set_default_tag(ASN1_TYPE node)
00799 {
00800 node_asn *p;
00801
00802 if((node==NULL) || (type_field(node->type)!=TYPE_DEFINITIONS))
00803 return ASN1_ELEMENT_NOT_FOUND;
00804
00805 p=node;
00806 while(p){
00807 if((type_field(p->type)==TYPE_TAG) &&
00808 !(p->type&CONST_EXPLICIT) &&
00809 !(p->type&CONST_IMPLICIT)){
00810 if(node->type&CONST_EXPLICIT) p->type|=CONST_EXPLICIT;
00811 else p->type|=CONST_IMPLICIT;
00812 }
00813
00814 if(p->down){
00815 p=p->down;
00816 }
00817 else if(p->right) p=p->right;
00818 else{
00819 while(1){
00820 p=_asn1_find_up(p);
00821 if(p==node){
00822 p=NULL;
00823 break;
00824 }
00825 if(p->right){
00826 p=p->right;
00827 break;
00828 }
00829 }
00830 }
00831 }
00832
00833 return ASN1_SUCCESS;
00834 }
00835
00836
00837
00838 static const char*
00839 parse_version_number( const char *s, int *number )
00840 {
00841 int val = 0;
00842
00843 if( *s == '0' && isdigit(s[1]) )
00844 return NULL;
00845 for ( ; isdigit(*s); s++ ) {
00846 val *= 10;
00847 val += *s - '0';
00848 }
00849 *number = val;
00850 return val < 0? NULL : s;
00851 }
00852
00853
00854
00855 static const char *
00856 parse_version_string( const char *s, int *major, int *minor, int *micro )
00857 {
00858 s = parse_version_number( s, major );
00859 if( !s || *s != '.' )
00860 return NULL;
00861 s++;
00862 s = parse_version_number( s, minor );
00863 if( !s || *s != '.' )
00864 return NULL;
00865 s++;
00866 s = parse_version_number( s, micro );
00867 if( !s )
00868 return NULL;
00869 return s;
00870 }
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 const char *
00883 asn1_check_version( const char *req_version )
00884 {
00885 const char *ver = LIBTASN1_VERSION;
00886 int my_major, my_minor, my_micro;
00887 int rq_major, rq_minor, rq_micro;
00888 const char *my_plvl, *rq_plvl;
00889
00890 if ( !req_version )
00891 return ver;
00892
00893 my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
00894 if ( !my_plvl )
00895 return NULL;
00896 rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
00897 &rq_micro );
00898 if ( !rq_plvl )
00899 return NULL;
00900
00901 if ( my_major > rq_major
00902 || (my_major == rq_major && my_minor > rq_minor)
00903 || (my_major == rq_major && my_minor == rq_minor
00904 && my_micro > rq_micro)
00905 || (my_major == rq_major && my_minor == rq_minor
00906 && my_micro == rq_micro
00907 && strcmp( my_plvl, rq_plvl ) >= 0) ) {
00908 return ver;
00909 }
00910 return NULL;
00911 }
00912
00913