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 
00204 int  get_size_toDER(Buffer pt, unsigned char node)
00205 {
00206     int  sz, div, cnt;
00207 
00208     sz = pt.vldsz;
00209     if (node==JBXL_ASN1_BIT) sz++;    
00210 
00211     cnt = 1;                    
00212     div = sz;
00213     if (div>=128) cnt++;        
00214     while (div>=256) {
00215         div >>= 8;
00216         cnt++;
00217     }
00218     sz = sz + cnt + 1;          
00219     return sz;
00220 }
00221 
00222 
00223 
00225 
00226 
00227 
00241 tDER*  DER_parse(tDER* der, Buffer* buf)
00242 {
00243     if (buf==NULL || buf->buf==NULL) return NULL;
00244 
00245     if (der==NULL) {
00246         der = new_DER_node();
00247         der->ldat.id = JBXL_ASN1_ANCHOR;
00248         der->ldat.lv = buf->vldsz;
00249         der->state   = JBXL_STATE_ANCHOR;
00250     }
00251     
00252     int sz = get_DER_size(buf->buf, NULL);
00253     if (sz > buf->vldsz) return NULL;     
00254 
00255     _DER_parse_children(der, buf);
00256     
00257     return der;
00258 }
00259 
00260 
00261 
00262 void  _DER_parse_children(tDER* der, Buffer* buf)
00263 {
00264     if (der==NULL) return;
00265     if (buf==NULL) buf = &(der->ldat.val);
00266     if (buf->buf==NULL) return;
00267 
00268     unsigned char* pp = buf->buf;
00269 
00270     int pos = 0;
00271     do {
00272         int sz = get_DER_size(pp+pos, NULL);
00273         if (sz > buf->vldsz - pos) return; 
00274 
00275         tDER* tmp = new_DER_node();
00276         int len = set_DER_node(tmp, pp+pos); 
00277         if (len==0) {
00278             del_DER_node(&tmp);
00279             return;
00280         }
00281         
00282         add_DER_node(der, tmp);
00283         if (tmp->ldat.id & JBXL_ASN1_CNSTRCTD) {
00284             _DER_parse_children(tmp, NULL);
00285             free_Buffer(&(tmp->ldat.val));      
00286         }
00287         pos += len;
00288 
00289     } while (pos<buf->vldsz);
00290     
00291     return;
00292 }
00293 
00294 
00295 
00306 int  set_DER_node(tDER* der, unsigned char* buf)
00307 {
00308     if (der==NULL || buf==NULL) return 0;
00309 
00310     int len = 0;
00311     int cnt = get_DER_size(buf, &len);
00312 
00313     der->ldat.id  = (int)(*buf);         
00314     der->ldat.lv  = cnt;
00315     der->ldat.val = set_Buffer((void*)(buf+cnt-len), len);
00316 
00317     return cnt;
00318 }
00319 
00320 
00321 
00334 int  get_DER_size(unsigned char* buf, int* valsz)
00335 {
00336     if (buf==NULL) return 0;
00337 
00338     int cnt = 0;
00339     int len = 0;
00340     cnt++;
00341     buf++;
00342     if (*buf>=0x80) {
00343         int i;
00344         int sz = (int)(*buf - 0x80);
00345         cnt++;
00346         buf++;
00347         for (i=0; i<sz; i++) {
00348             len = len*256 + (int)(*buf);
00349             cnt++;
00350             buf++;
00351         } 
00352     }
00353     else {
00354         len  = (int)(*buf);
00355         cnt++;
00356         buf++;
00357     }
00358     
00359     if (valsz!=NULL) *valsz = len;
00360     cnt += len;
00361 
00362     return cnt;
00363 }
00364 
00365 
00366 
00376 
00385 void  print_tDER(FILE* fp, tDER* pp)
00386 {
00387     if (fp==NULL) fp = stderr;
00388 
00389     if (pp!=NULL) {
00390         while(pp->esis!=NULL) pp = pp->esis;
00391         do {
00392             int i;
00393             tList_data ld = pp->ldat;
00394 
00395             for(i=0; i<pp->depth; i++) fprintf(fp, "    ");
00396             if (pp->depth>0) fprintf(fp, " -> ");
00397             fprintf(fp, "%d: ", pp->depth);
00398             asn1_print_id(fp, ld.id);
00399             fprintf(fp, "%d, %d ", ld.lv, ld.val.vldsz);
00400             asn1_print_tag_value(fp, ld.id, ld.val);
00401             fprintf(fp, "\n");
00402 
00403             if (pp->next!=NULL) print_tDER(fp, pp->next);
00404 
00405             pp = pp->ysis;
00406             
00407             
00408             
00409         } while(pp!=NULL);
00410     }
00411     else {
00412         fprintf(fp, "(Tree is NULL)\n");
00413     }
00414     fflush(fp);
00415 
00416     return;
00417 }
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428