00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <ctype.h>
00027 #include <sys/types.h>
00028
00029 #ifdef WIN32
00030 #include <winsock.h>
00031 #endif
00032
00033 #include "asn1.h"
00034
00035
00036
00037
00038 #define SF_ASN1_CLASS(c) (((u_char)c) & SF_ASN1_CLASS_MASK)
00039 #define SF_ASN1_FLAG(c) (((u_char)c) & SF_ASN1_FLAG_MASK)
00040 #define SF_ASN1_TAG(c) (((u_char)c) & SF_ASN1_TAG_MASK)
00041 #define SF_ASN1_LEN_EXT(c) (((u_char)c) & SF_BER_LEN_MASK)
00042
00043 #define ASN1_OOB(s,e,d) (!(((s) <= (d)) && ((d) < (e))))
00044 #define ASN1_FATAL_ERR(e) ((e) < 0)
00045 #define ASN1_NONFATAL_ERR(e) ((e) > 0)
00046
00047 #define ASN1_MAX_STACK 128
00048
00049 static ASN1_TYPE *g_asn1_mem = NULL;
00050 static int g_asn1_max_nodes = 0;
00051 static int g_asn1_node_index = 0;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 static void asn1_init_node_index(void)
00064 {
00065 g_asn1_node_index = 0;
00066
00067 return;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 static ASN1_TYPE *asn1_node_alloc(void)
00083 {
00084 if(!g_asn1_mem || (g_asn1_max_nodes <= g_asn1_node_index))
00085 return NULL;
00086
00087 return &g_asn1_mem[g_asn1_node_index++];
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 int asn1_init_mem(int iNodes)
00106 {
00107 if(iNodes <= 0)
00108 return ASN1_ERR_INVALID_ARG;
00109
00110
00111
00112
00113 if(g_asn1_mem && g_asn1_max_nodes > 0)
00114 return ASN1_OK;
00115
00116 g_asn1_mem = (ASN1_TYPE *)malloc(sizeof(ASN1_TYPE)*iNodes);
00117 if(!g_asn1_mem)
00118 return ASN1_ERR_MEM_ALLOC;
00119
00120 g_asn1_max_nodes = iNodes;
00121
00122 return ASN1_OK;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 static int asn1_decode_tag_num_ext(ASN1_DATA *asn1_data, u_int *tag_num)
00144 {
00145 int iExtension = 0;
00146 u_int new_tag_num;
00147
00148 if(!asn1_data || !tag_num)
00149 return ASN1_ERR_NULL_MEM;
00150
00151 *tag_num = 0;
00152
00153
00154
00155
00156 do
00157 {
00158
00159
00160
00161 iExtension = SF_ASN1_LEN_EXT(*asn1_data->data);
00162
00163 new_tag_num = ((*tag_num << 7) | (*asn1_data->data & 0x7f));
00164 if(*tag_num != 0 && new_tag_num <= *tag_num)
00165 {
00166 return ASN1_ERR_OVERLONG_LEN;
00167 }
00168
00169 *tag_num = new_tag_num;
00170
00171 asn1_data->data++;
00172 if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data))
00173 {
00174 return ASN1_ERR_OOB;
00175 }
00176
00177 } while(iExtension);
00178
00179 return ASN1_OK;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 static int asn1_decode_ident(ASN1_TYPE *asn1_type, ASN1_DATA *asn1_data)
00199 {
00200 ASN1_IDENT *ident;
00201 int iRet;
00202
00203 if(!asn1_type || !asn1_data)
00204 return ASN1_ERR_NULL_MEM;
00205
00206 ident = &asn1_type->ident;
00207
00208 ident->class = SF_ASN1_CLASS(*asn1_data->data);
00209 ident->flag = SF_ASN1_FLAG(*asn1_data->data);
00210 ident->tag = SF_ASN1_TAG(*asn1_data->data);
00211
00212 asn1_data->data++;
00213 if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data))
00214 {
00215
00216 return ASN1_ERR_OOB;
00217 }
00218
00219
00220
00221
00222 if(ident->tag == SF_ASN1_TAG_EXTENSION)
00223 {
00224 ident->tag_type = SF_ASN1_TAG_EXTENSION;
00225
00226 iRet = asn1_decode_tag_num_ext(asn1_data, &ident->tag);
00227 if(iRet)
00228 {
00229
00230 return ASN1_ERR_INVALID_BER_TAG_LEN;
00231 }
00232 }
00233
00234 return ASN1_OK;
00235 }
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 static int asn1_decode_len_type(u_char *data)
00252 {
00253 int iExt;
00254
00255 iExt = SF_ASN1_LEN_EXT(*data);
00256 if(iExt)
00257 {
00258 if(*data & 0x7f)
00259 {
00260 return SF_BER_LEN_DEF_LONG;
00261 }
00262 else
00263 {
00264 return SF_BER_LEN_INDEF;
00265 }
00266 }
00267
00268 return SF_BER_LEN_DEF_SHORT;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 static int asn1_decode_len_ext(ASN1_DATA *asn1_data, u_int *size)
00290 {
00291 int iBytes;
00292 int iCtr;
00293 u_int new_size;
00294
00295 if(!asn1_data || !size)
00296 return ASN1_ERR_NULL_MEM;
00297
00298 *size = 0;
00299
00300 iBytes = (*asn1_data->data & 0x7f);
00301
00302 asn1_data->data++;
00303 if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data))
00304 {
00305 return ASN1_ERR_OOB;
00306 }
00307
00308 for(iCtr = 0; iCtr < iBytes; iCtr++)
00309 {
00310 new_size = ((*size << 8) | (*asn1_data->data));
00311
00312
00313
00314
00315
00316
00317 if(*size != 0 && new_size <= *size)
00318 {
00319 return ASN1_ERR_OVERLONG_LEN;
00320 }
00321
00322 *size = new_size;
00323
00324 asn1_data->data++;
00325 if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data))
00326 {
00327
00328
00329
00330
00331 if(*size == 0 && (iCtr+1) == iBytes)
00332 break;
00333
00334 return ASN1_ERR_OOB;
00335 }
00336 }
00337
00338 return ASN1_OK;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356 static int asn1_decode_len(ASN1_TYPE *asn1_type, ASN1_DATA *asn1_data)
00357 {
00358 ASN1_LEN *len;
00359 int iRet;
00360
00361 if(!asn1_type || !asn1_data)
00362 return ASN1_ERR_NULL_MEM;
00363
00364 len = &asn1_type->len;
00365
00366 len->type = asn1_decode_len_type(asn1_data->data);
00367
00368 switch(len->type)
00369 {
00370 case SF_BER_LEN_DEF_SHORT:
00371 len->size = *asn1_data->data;
00372
00373 (asn1_data->data)++;
00374 if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data))
00375 {
00376
00377
00378
00379
00380 if(len->size != 0)
00381 return ASN1_ERR_OOB;
00382 }
00383
00384 break;
00385
00386 case SF_BER_LEN_DEF_LONG:
00387 iRet = asn1_decode_len_ext(asn1_data, &len->size);
00388 if(iRet)
00389 return iRet;
00390
00391 break;
00392
00393 case SF_BER_LEN_INDEF:
00394
00395
00396
00397
00398 len->size = 0;
00399
00400 asn1_data->data++;
00401 if(ASN1_OOB(asn1_data->start, asn1_data->end, asn1_data->data))
00402 return ASN1_ERR_OOB;
00403
00404 break;
00405
00406 default:
00407
00408
00409
00410
00411 return ASN1_ERR_FATAL;
00412 }
00413
00414 return ASN1_OK;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 static int asn1_is_eoc(ASN1_TYPE *asn1)
00431 {
00432 if(!asn1)
00433 return 0;
00434
00435 if(asn1->ident.class == 0x00 && asn1->ident.flag == 0x00 &&
00436 asn1->ident.tag == 0x00 && asn1->len.type == SF_BER_LEN_DEF_SHORT &&
00437 asn1->len.size == 0)
00438 {
00439 return 1;
00440 }
00441
00442 return 0;
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471 static int asn1_decode_type(u_char **data, u_int *len, ASN1_TYPE **asn1_type)
00472 {
00473 ASN1_DATA asn1data;
00474 u_int uiRawLen;
00475 int iRet;
00476
00477 if(!*data)
00478 return ASN1_ERR_INVALID_ARG;
00479
00480 *asn1_type = NULL;
00481
00482
00483
00484
00485
00486
00487 if(*len == 0)
00488 return ASN1_OK;
00489
00490 if(ASN1_OOB(*data, (*data) + *len, *data))
00491 return ASN1_ERR_OOB;
00492
00493 *asn1_type = asn1_node_alloc();
00494 if(*asn1_type == NULL)
00495 {
00496 return ASN1_ERR_MEM_ALLOC;
00497 }
00498 memset(*asn1_type, 0x00, sizeof(ASN1_TYPE));
00499
00500 asn1data.start = *data;
00501 asn1data.end = (*data) + *len;
00502 asn1data.data = *data;
00503
00504 iRet = asn1_decode_ident(*asn1_type, &asn1data);
00505 if(iRet)
00506 {
00507 return iRet;
00508 }
00509
00510 iRet = asn1_decode_len(*asn1_type, &asn1data);
00511 if(iRet)
00512 {
00513 return iRet;
00514 }
00515
00516
00517
00518
00519
00520 uiRawLen = asn1data.end - asn1data.data;
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 if(!(*asn1_type)->len.size)
00531 {
00532 if((*asn1_type)->len.type != SF_BER_LEN_INDEF ||
00533 (*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT)
00534 {
00535 (*asn1_type)->data = asn1data.data;
00536
00537 if((*asn1_type)->len.type == SF_BER_LEN_INDEF)
00538 {
00539 (*asn1_type)->data_len = uiRawLen;
00540 }
00541 else
00542 {
00543
00544
00545
00546
00547 (*asn1_type)->data_len = 0;
00548
00549 if(asn1_is_eoc(*asn1_type))
00550 (*asn1_type)->eoc = 1;
00551 }
00552
00553 goto valid;
00554 }
00555
00556 return ASN1_ERR_INVALID_INDEF_LEN;
00557 }
00558
00559
00560
00561
00562 (*asn1_type)->data = asn1data.data;
00563
00564
00565
00566
00567 if(uiRawLen < (*asn1_type)->len.size)
00568 {
00569 (*asn1_type)->data_len = uiRawLen;
00570
00571
00572
00573
00574
00575 if((*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT)
00576 goto valid;
00577
00578 return ASN1_ERR_OOB;
00579 }
00580
00581
00582
00583
00584
00585 (*asn1_type)->data_len = (*asn1_type)->len.size;
00586
00587
00588
00589
00590
00591 if(!((*asn1_type)->ident.flag == SF_ASN1_FLAG_CONSTRUCT))
00592 {
00593 asn1data.data += (*asn1_type)->len.size;
00594 }
00595
00596 valid:
00597
00598
00599
00600
00601
00602 *len = asn1data.end - asn1data.data;
00603 *data = asn1data.data;
00604
00605 return ASN1_OK;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 int asn1_decode(u_char *data, u_int len, ASN1_TYPE **asn1_type)
00623 {
00624 ASN1_TYPE *cur;
00625 ASN1_TYPE *child = NULL;
00626 ASN1_TYPE *indef;
00627 ASN1_TYPE *asnstack[ASN1_MAX_STACK];
00628
00629 u_char *end;
00630 u_int con_len;
00631 int index = 0;
00632 int iRet;
00633
00634 if(!data || !len)
00635 return ASN1_ERR_NULL_MEM;
00636
00637 asn1_init_node_index();
00638
00639
00640
00641
00642
00643 end = data + len;
00644
00645 iRet = asn1_decode_type(&data,&len,asn1_type);
00646 if(iRet || !(*asn1_type))
00647 {
00648
00649 return iRet;
00650 }
00651
00652 cur = *asn1_type;
00653
00654 while(cur)
00655 {
00656
00657
00658
00659
00660
00661 while(cur && cur->ident.flag == SF_ASN1_FLAG_CONSTRUCT)
00662 {
00663 if(index < ASN1_MAX_STACK)
00664 asnstack[index++] = cur;
00665 else
00666 return ASN1_ERR_STACK;
00667
00668
00669
00670
00671
00672 if(cur->len.type != SF_BER_LEN_INDEF)
00673 {
00674 if(len < cur->data_len)
00675 return ASN1_ERR_OVERLONG_LEN;
00676
00677 len = cur->data_len;
00678 }
00679
00680 iRet = asn1_decode_type(&data, &len, &cur->cnext);
00681 if(iRet)
00682 {
00683 return iRet;
00684 }
00685
00686
00687
00688
00689 if(cur->cnext && cur->cnext->eoc)
00690 {
00691 if(index && (indef = asnstack[--index]))
00692 {
00693 if(indef->len.type == SF_BER_LEN_INDEF)
00694 {
00695 indef->len.size = data - indef->data - 2;
00696 indef->data_len = indef->len.size;
00697
00698 cur->cnext = NULL;
00699 cur = indef;
00700 break;
00701 }
00702 else
00703 {
00704
00705
00706
00707
00708 asnstack[index++] = indef;
00709 }
00710 }
00711 }
00712
00713 cur = cur->cnext;
00714 }
00715
00716
00717
00718
00719 if(cur)
00720 {
00721 iRet = asn1_decode_type(&data, &len, &cur->next);
00722 if(iRet)
00723 return iRet;
00724
00725
00726
00727
00728 while(cur->next && cur->next->eoc)
00729 {
00730 if(index && (indef = asnstack[--index]))
00731 {
00732 if(indef->len.type == SF_BER_LEN_INDEF)
00733 {
00734 indef->len.size = data - indef->data - 2;
00735 indef->data_len = indef->len.size;
00736 cur->next = NULL;
00737 cur = indef;
00738
00739 iRet = asn1_decode_type(&data, &len, &cur->next);
00740 if(iRet)
00741 {
00742 return iRet;
00743 }
00744
00745 continue;
00746 }
00747
00748 asnstack[index++] = indef;
00749 }
00750
00751 break;
00752 }
00753
00754 cur = cur->next;
00755 if(cur) continue;
00756 }
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766 while(index && (cur = asnstack[--index]))
00767 {
00768
00769
00770
00771
00772 con_len = data - cur->data;
00773 if(cur->data_len > con_len)
00774 {
00775 len = cur->data_len - con_len;
00776 }
00777
00778
00779
00780
00781
00782 if(len == 0)
00783 {
00784 child = cur;
00785 }
00786 else if(child)
00787 {
00788
00789
00790
00791
00792
00793
00794 asnstack[index++] = cur;
00795 cur = child;
00796 child = NULL;
00797 }
00798
00799 iRet = asn1_decode_type(&data, &len, &cur->next);
00800 if(iRet)
00801 {
00802 return iRet;
00803 }
00804
00805 if(cur->next && cur->next->eoc)
00806 {
00807 if(index && (indef = asnstack[--index]))
00808 {
00809 if(indef->len.type == SF_BER_LEN_INDEF)
00810 {
00811 indef->len.size = data - indef->data - 2;
00812 indef->data_len = indef->len.size;
00813 cur->next = NULL;
00814 cur = indef;
00815 }
00816 else
00817 {
00818 asnstack[index++] = indef;
00819 }
00820 }
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832 if(!index && !(cur->next) && (data < end))
00833 {
00834 len = (end - data);
00835
00836 iRet = asn1_decode_type(&data, &len, &cur->next);
00837 if(iRet)
00838 return iRet;
00839 }
00840
00841 cur = cur->next;
00842 if(cur)
00843 break;
00844 }
00845
00846
00847
00848
00849 }
00850
00851 return ASN1_OK;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868 int asn1_traverse(ASN1_TYPE *asn1, void *user,
00869 int (*DetectFunc)(ASN1_TYPE *, void *))
00870 {
00871 ASN1_TYPE *asnstack[ASN1_MAX_STACK];
00872 int index = 0;
00873 ASN1_TYPE *cur;
00874 int iRet;
00875
00876 if(!asn1)
00877 return 0;
00878
00879 cur = asn1;
00880
00881 while(cur)
00882 {
00883 while(cur && cur->ident.flag == SF_ASN1_FLAG_CONSTRUCT)
00884 {
00885 if(index < ASN1_MAX_STACK)
00886 asnstack[index++] = cur;
00887 else
00888 return 0;
00889
00890 iRet = DetectFunc(cur, user);
00891 if(iRet)
00892 return 1;
00893
00894 cur = cur->cnext;
00895 }
00896
00897 if(cur)
00898 {
00899 iRet = DetectFunc(cur, user);
00900 if(iRet)
00901 return 1;
00902
00903 cur = cur->next;
00904 if(cur) continue;
00905 }
00906
00907 while(index && (cur = asnstack[--index]))
00908 {
00909 cur = cur->next;
00910 if(cur)
00911 break;
00912 }
00913 }
00914
00915 return 0;
00916 }
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 int asn1_print_types(ASN1_TYPE *asn1_type, void *user)
00930 {
00931 unsigned int iTabs = 0;
00932 unsigned int iCtr;
00933
00934 if(user)
00935 iTabs = *((int *)user);
00936
00937 for(iCtr = 0; iCtr < iTabs; iCtr++)
00938 printf(" ");
00939
00940 printf("## PRINT ASN1_TYPE STRUCTURE ##\n");
00941
00942 for(iCtr = 0; iCtr < iTabs; iCtr++)
00943 printf(" ");
00944
00945 printf("IDENT - class: %.2x | flag: %.2x | tag_type: %.2x | "
00946 "tag_num: %d\n", asn1_type->ident.class, asn1_type->ident.flag,
00947 asn1_type->ident.tag_type, asn1_type->ident.tag);
00948
00949 for(iCtr = 0; iCtr < iTabs; iCtr++)
00950 printf(" ");
00951
00952 printf("LEN - type: %d | size: %u\n", asn1_type->len.type,
00953 asn1_type->len.size);
00954
00955 for(iCtr = 0; iCtr < iTabs; iCtr++)
00956 printf(" ");
00957
00958 printf("DATA | data_len: %d | ", asn1_type->data_len);
00959 if(asn1_type->data)
00960 {
00961 for(iCtr = 0; iCtr < asn1_type->data_len; iCtr++)
00962 printf(" %.2x", asn1_type->data[iCtr]);
00963 }
00964 else
00965 {
00966 printf(" NULL");
00967 }
00968
00969 printf("\n\n");
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 return 0;
00988 }
00989
00990 #ifdef I_WANT_MAIN_DAMMIT
00991 static int BitStringOverflow(ASN1_TYPE *asn1_type)
00992 {
00993 if(!asn1_type)
00994 return 0;
00995
00996 if(asn1_type->ident.tag == SF_ASN1_TAG_BIT_STR && !asn1_type->ident.flag)
00997 {
00998 if(((asn1_type->len.size - 1)*8) < (u_int)asn1_type->data[0])
00999 {
01000 return 1;
01001 }
01002 }
01003
01004 return 0;
01005 }
01006
01007
01008
01009
01010
01011
01012 int main(int argc, char **argv)
01013 {
01014 ASN1_TYPE *asn1_type;
01015 char line[10000];
01016 u_int ctmp;
01017 char *buf;
01018 int buf_size;
01019 int iCtr;
01020 int iRet;
01021
01022 fgets(line, sizeof(line), stdin);
01023 buf_size = strlen(line);
01024
01025 while(buf_size && line[buf_size-1] <= 0x20)
01026 {
01027 buf_size--;
01028 line[buf_size] = 0x00;
01029 }
01030
01031 if(!buf_size)
01032 {
01033 printf("** No valid characters in data string.\n");
01034 return 1;
01035 }
01036
01037 if(buf_size % 2)
01038 {
01039 printf("** Data must be represent in hex, meaning that there is an "
01040 "odd number of characters in the data string.\n");
01041 return 1;
01042 }
01043
01044 buf_size >>= 1;
01045
01046 buf = (char *)malloc(buf_size + 1);
01047 if(!buf)
01048 {
01049 printf("** Bad malloc\n");
01050 return 1;
01051 }
01052
01053 for(iCtr = 0; iCtr < buf_size; iCtr++)
01054 {
01055 if(!(isxdigit(line[iCtr*2]) && isxdigit(line[(iCtr*2)+1])))
01056 {
01057 printf("** Data stream is not all hex digits.\n");
01058 return 1;
01059 }
01060
01061 sscanf(&line[iCtr*2], "%2x", &ctmp);
01062 buf[iCtr] = (char)ctmp;
01063 }
01064
01065 buf[iCtr] = 0x00;
01066
01067 if(asn1_init_mem(256))
01068 {
01069 printf("** asn1_init_mem() failed\n");
01070 return 1;
01071 }
01072
01073 iRet = asn1_decode(buf, buf_size, &asn1_type);
01074 if(iRet && !asn1_type)
01075 {
01076 printf("** FAILED\n");
01077 return 1;
01078 }
01079
01080 printf("** iRet = %d\n", iRet);
01081
01082 asn1_print_types(asn1_type, 0);
01083
01084 free(buf);
01085
01086 return 0;
01087 }
01088 #endif