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