00001 
00009 #include "asn1_tool.h"
00010 
00011 
00013 
00014 
00015 
00036 int  skip_DER_node(Buffer param, unsigned char node, int ls, int* lp) 
00037 {
00038     int i, sz=-1;
00039 
00040     if ((unsigned char)param.buf[ls]==node) {
00041         if ((unsigned char)param.buf[ls+1]>=0x80) {
00042             sz = (int)param.buf[ls+1] - 128;
00043             *lp = 0;
00044             for (i=ls+2; i<ls+sz+2; i++) {
00045                 *lp *= 256;
00046                 *lp += (unsigned char)param.buf[i];
00047             }    
00048         }
00049         else {
00050             sz = 0;
00051             *lp = (int)param.buf[ls+1];
00052         }
00053         
00054         sz = ls + sz + 2;
00055     }
00056 
00057     return sz;
00058 }
00059 
00060 
00061 
00073 Buffer  node2DER(Buffer pt, unsigned char node)
00074 {
00075     int  sz, len, pp;
00076     unsigned char cnt;
00077     Buffer    buf;
00078 
00079     len = get_size_toDER(pt, node);  
00080     buf = make_Buffer(len);
00081     sz = pt.vldsz;
00082     pp = len - sz;                  
00083     memcpy(buf.buf+pp, pt.buf, sz);
00084 
00085     pp--;
00086     if (node==JBXL_ASN1_INT) {
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094     }
00095     else if (node==JBXL_ASN1_BIT) {
00096         sz++;
00097         buf.buf[pp--] = 0x00;
00098     }
00099 
00100     buf.buf[0] = node;
00101 
00102     cnt = 0;
00103     if (sz>=128) {
00104         cnt++;
00105         while (sz>=256) {
00106             buf.buf[pp--] = sz % 256;
00107             sz >>= 8;
00108             cnt++;
00109         }
00110         buf.buf[pp] = (unsigned char)sz;
00111         buf.buf[1]  = 0x80 + cnt;
00112     }
00113     else {
00114         buf.buf[1] = (unsigned char)sz;
00115     }
00116 
00117     buf.vldsz = len;
00118     return buf;
00119 }
00120 
00121 
00122 
00133 Buffer  int2bin_DER(long int n)
00134 {
00135     int  ii, cnt;
00136     unsigned long int div;
00137     Buffer bin;
00138 
00139     cnt = 1;
00140     div = n;
00141     while(div>=256) {
00142         div >>= 8;
00143         cnt++;
00144     }
00145     bin = make_Buffer(cnt+1);           
00146     ii = cnt - 1;
00147 
00148     while(n>=256) {
00149         bin.buf[ii--] = (unsigned char)(n % 256);
00150         n >>= 8;
00151     }
00152     bin.buf[0] = (unsigned char)n;
00153 
00154     
00155     if (n>0 && bin.buf[0]>=0x80) {     
00156         for (ii=cnt; ii>0; ii--) bin.buf[ii] = bin.buf[ii-1];
00157         bin.buf[0] = 0x00;
00158         cnt++;
00159     }
00160 
00161     bin.vldsz  = cnt;
00162 
00163     return bin;
00164 }
00165 
00166 
00167 
00168 long int  bin2int_DER(Buffer buf)
00169 {
00170     if (buf.buf==NULL || buf.vldsz==0) return 0;
00171 
00172     int i;
00173     int sz = buf.vldsz;
00174     unsigned char* pp = buf.buf;
00175 
00176     int minus = OFF;
00177     if (*pp & 0x80) {   
00178         minus = ON;
00179         for (i=0; i<sz; i++) pp[i] = pp[i] ^ 0xff;  
00180     }
00181 
00182     long int ret = pp[sz-1];
00183     for (i=sz-2; i>=0; i--) {
00184         ret += pp[i] * 256;
00185     }
00186     if (minus) ret = - (ret + 1);
00187 
00188     return ret;
00189 }
00190 
00191 
00192 
00193 
00205 int  get_size_toDER(Buffer pt, unsigned char node)
00206 {
00207     int  sz, div, cnt;
00208 
00209     sz = pt.vldsz;
00210     if (node==JBXL_ASN1_BIT) sz++;    
00211 
00212     cnt = 1;                    
00213     div = sz;
00214     if (div>=128) cnt++;        
00215     while (div>=256) {
00216         div >>= 8;
00217         cnt++;
00218     }
00219     sz = sz + cnt + 1;          
00220     return sz;
00221 }
00222 
00223 
00224 
00225 
00227 
00228 
00229 
00261 tDER*  DER_parse(tDER* der, Buffer* buf)
00262 {
00263     if (buf==NULL || buf->buf==NULL) return NULL;
00264 
00265     if (der==NULL) {
00266         der = new_DER_node();
00267         der->ldat.id = JBXL_ASN1_ANCHOR;
00268         der->ldat.lv = buf->vldsz;
00269         der->state   = JBXL_STATE_ANCHOR;
00270     }
00271     
00272     int sz = get_DER_size(buf->buf, NULL);
00273     if (sz > buf->vldsz) return NULL;     
00274 
00275     _DER_parse_children(der, buf);
00276     
00277     return der;
00278 }
00279 
00280 
00281 
00282 void  _DER_parse_children(tDER* der, Buffer* buf)
00283 {
00284     if (der==NULL) return;
00285     if (buf==NULL) buf = &(der->ldat.val);
00286     if (buf->buf==NULL) return;
00287 
00288     unsigned char* pp = buf->buf;
00289 
00290     int pos = 0;
00291     do {
00292         int sz = get_DER_size(pp+pos, NULL);
00293         if (sz > buf->vldsz - pos) return; 
00294 
00295         tDER* tmp = new_DER_node();
00296         int len = set_DER_node(tmp, pp+pos); 
00297         if (len==0) {
00298             del_DER_node(&tmp);
00299             return;
00300         }
00301         
00302         add_DER_node(der, tmp);
00303         if (tmp->ldat.id & JBXL_ASN1_CNSTRCTD) {
00304             _DER_parse_children(tmp, NULL);
00305             free_Buffer(&(tmp->ldat.val));      
00306         }
00307         pos += len;
00308 
00309     } while (pos<buf->vldsz);
00310     
00311     return;
00312 }
00313 
00314 
00315 
00326 int  set_DER_node(tDER* der, unsigned char* buf)
00327 {
00328     if (der==NULL || buf==NULL) return 0;
00329 
00330     int len = 0;
00331     int cnt = get_DER_size(buf, &len);
00332 
00333     der->ldat.id  = (int)(*buf);         
00334     der->ldat.lv  = cnt;
00335     der->ldat.val = set_Buffer((void*)(buf+cnt-len), len);
00336 
00337     return cnt;
00338 }
00339 
00340 
00341 
00354 int  get_DER_size(unsigned char* buf, int* valsz)
00355 {
00356     if (buf==NULL) return 0;
00357 
00358     int cnt = 0;
00359     int len = 0;
00360     cnt++;
00361     buf++;
00362     if (*buf>=0x80) {
00363         int i;
00364         int sz = (int)(*buf - 0x80);
00365         cnt++;
00366         buf++;
00367         for (i=0; i<sz; i++) {
00368             len = len*256 + (int)(*buf);
00369             cnt++;
00370             buf++;
00371         } 
00372     }
00373     else {
00374         len  = (int)(*buf);
00375         cnt++;
00376         buf++;
00377     }
00378     
00379     if (valsz!=NULL) *valsz = len;
00380     cnt += len;
00381 
00382     return cnt;
00383 }
00384 
00385 
00386 
00395 void  print_tDER(FILE* fp, tDER* pp)
00396 {
00397     if (fp==NULL) fp = stderr;
00398 
00399     if (pp!=NULL) {
00400         while(pp->esis!=NULL) pp = pp->esis;
00401         do {
00402             int i;
00403             tList_data ld = pp->ldat;
00404 
00405             for(i=0; i<pp->depth; i++) fprintf(fp, "    ");
00406             if (pp->depth>0) fprintf(fp, " -> ");
00407             fprintf(fp, "%d: ", pp->depth);
00408             asn1_print_node(fp, ld.id);
00409             fprintf(fp, "%d,%d ", ld.lv, ld.val.vldsz);
00410             asn1_print_node_value(fp, ld.id, ld.val);
00411             fprintf(fp, "\n");
00412 
00413             if (pp->next!=NULL) print_tDER(fp, pp->next);
00414 
00415             pp = pp->ysis;
00416             
00417             
00418             
00419         } while(pp!=NULL);
00420     }
00421     else {
00422         fprintf(fp, "(Tree is NULL)\n");
00423     }
00424     fflush(fp);
00425 
00426     return;
00427 }
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438